The lead cars all stayed out on slick tyres through the first period of rain, but the teams knew more rain was coming and as it came down more heavily Verstappen benefited from an early stop for intermediates on lap 26.
Norris, Hamilton and Russell followed him in a lap later, Piastri suffering badly for staying out a further lap on the slicks and losing 10 seconds to the lead pack.
The stop timing vaulted Verstappen up to third behind Norris and Hamilton, with Russell fourth.
But four laps later Russell was out of the running when he was told to retire his Mercedes because of a water system problem.
By lap 38, with 14 to go, the track was almost dry, and Verstappen again jumped early for a tyre change.
He and Hamilton stopped together, Mercedes choosing soft tyres and Verstappen hard, while Norris stayed out a lap later before taking softs.
It set up a grandstand finish, with the three cars in a single camera shot on the Hangar Straight for the entire climactic period of the race.
Hamilton always looked to have Norris under control, but the it was soon clear that Verstappen was now the major threat, the Red Bull transformed by the decision to switch to hard tyres.
Verstappen swept by Norris on lap 48 down the Hangar Straight, and went into the final four laps 3.2 seconds behind Hamilton and closing in.
But Hamilton had enough to hold him off, crossing the line 1.4secs adrift, before Hamilton fought back tears after climbing out of the car.
Behind Sainz, Hulkenberg impressed in a Haas heavily upgraded for this race in sixth place, while Aston Martin’s Lance Stroll and Fernando Alonso took seventh and eighth as Williams’ Alex Albon and RB’s Yuki Tsunoda completed the points positions in the top 10.