Verstappen grabbed the race by the throat with a brilliant opening few laps at the Circuit de Barcelona-Catalunya.
He made a slightly better start than Norris and was able to get his front wing inside the McLaren on the run to the first corner.
Norris defended robustly, even forcing Verstappen on to the grass, but was able to fend off the Red Bull.
Verstappen passed Norris on the inside as Russell took advantage of their tussle to pass both to grab the lead from fourth on the grid.
Verstappen then passed Russell at the start of lap three in a decisive and committed move around the outside of Turn One, while Norris was stuck behind the Mercedes for a further 12 laps.
It forced Norris and McLaren into an off-set strategy, trying to run longer and then come back at Verstappen on fresher tyres.
But it left him too much to do and he had to settle for second behind the Red Bull driver, who yet again proved himself the class of the field.
Verstappen had a four-second advantage when he made his first stop on lap 17, and McLaren decided to leave Norris out, waiting a further seven laps before his stop.
He had to fight his way back past first the Ferrari of Carlos Sainz and then the Mercedes of Russell and Hamilton before closing in on Verstappen.
Norris got to within 4.7 seconds of the Red Bull before Verstappen peeled in for his final stop on lap 44, and was 6.8secs adrift after emerging from his own final stop three laps later.
Norris edged closer to Verstappen over the final stint but he had been left with too much to do and crossed the line two seconds behind.
Hamilton’s third place – thanks to some decisive overtaking moves, including a very aggressive one on Sainz – confirmed Mercedes’ emergence as contenders after a series of upgrades, while fifth and sixth on the grid and in the race was a disappointing result for a Ferrari team who had a major upgrade for this race.
Leclerc was on Russell’s tail on the final lap but the Mercedes managed to hold him off.
McLaren’s Oscar Piastri moved up from 10th on the gird to finish seventh, while Red Bull’s Sergio Perez passed Pierre Gasly’s Alpine late on to take eighth.
The second Alpine of Esteban Ocon took the final point in 10th place.