Verstappen's hard starting tyres paid off immediately in the first stint, while polesitter Bottas lost out in a late wheel-to-wheel fight with Hamilton, who had run longer in the middle phase of the race.
Charles Leclerc took another unexpectedly high result for Ferrari with fourth, while teammate Sebastian Vettel had to put in a recovery drive after spinning at the start.
At the start, Bottas held the lead off the line while behind the two Mercedes cars Verstappen immediately launched past Hulkenberg to seize third.
In the pack behind, Vettel spun at the first corner after getting onto the inside kerb at Abbey while following Leclerc – with Vettel fortunate not to wipe out Carlos Sainz as he snapped left and fell to the rear of the field.
Hamilton chased Bottas and attacked around the outside going into Brooklands – echoing their battle at the same spot from the 2019 British GP – but Bottas shrugged off his teammate's attention and moved clear in first.
The two Mercedes drivers initially pulled clear of Verstappen, but the Red Bull driver used his hard tyre advantage to close in as the first stint wore on.
Red Bull even warned Verstappen he was getting too close – a call he swiftly rebuffed – and he continued to home in on Hamilton, with both Mercedes drivers beginning to struggle for tyre life with the race barely 10 laps old.
As Verstappen twice had a look to Hamilton's inside at Copse, with the gap between the pair at the 0.5s mark, Mercedes called Bottas in to switch his blistered mediums for hards at the end of lap13 of 52.
Hamilton came in at the end of the next lap to leave Verstappen in the lead.
The Mercedes drivers, particularly Bottas, immediately moved to set their quickest laps of the race at that stage, but it soon became clear that Verstappen was able to lap fastest despite his tyres having done Q2 and the opening stint.
Both Bottas and Hamilton looked to be struggling with blisters on their hards and set a series of times in the 1m32s, while Verstappen was able to run comfortably in the 1m31s.
He continued until lap 26 to take the medium tyres and rejoined just behind Bottas at the pit exit.
But with the benefit of fresh rubber and DRS he attacked down the Wellington Straight and to the inside of Brooklands.
Bottas stayed in front but not for long as Verstappen ran easily around the outside of Luffield to retake the lead as they accelerated out of the long right-hander.
Verstappen used his new tyres to set a series of personal bests and eek out a lead over Bottas, before Red Bull asked him to abandon all tyre management – just as Bottas had set the races fastest lap.
The Red Bull driver soon retook that accolade and raced clear on a rather short second stint, with Verstappen and Bottas coming in together on lap 32 – Verstappen to go back to hards and Bottas to take another set of the white-walled rubber.
Mercedes left Hamilton out for another nine laps, with Red Bull briefly concerned he would try to go to the end despite the blisters down the middle of both of the world champion's rear tyres.
He rejoined in fourth behind Leclerc, who had risen up the order from eighth on the grid with an unseen but effective one-stopper, and he immediately lit up the time screens.
Hamilton did not immediately clear the Ferrari – doing so to the inside of Stowe despite a late and firm move from Leclerc to cover the attack on lap 45 – but when he did he homed in on Bottas, with both Mercedes drivers told they were "free to race".
By the end of lap 49 Hamilton was all over Bottas's rear and he blasted by with DRS on the Wellington Straight to take second.
Verstappen had a near nine-second lead which never looked in danger of being eroded in the final few laps and he roared home to take his first win of the season, with the Mercedes drivers significantly slower on the last lap.
Leclerc held on to make his one-stop work and take an unexpected fourth for Ferrari, with Alex Albon recovering to fifth after starting ninth in the second Red Bull.
He put in a series of bold passes around the outside of Copse – including moves on Kimi Raikkonen and Lando Norris – after Red Bull brought him in early to get rid of the mediums he had started on.
Albon demoted Lance Stroll to sixth late on, with Nico Hulkenberg ending up seventh as he required an extra third stop – for the unfancied softs – in the closing stages of his F1 return.
Esteban Ocon also made a one-stopper work to go from his penalised grid position of P14 to eighth, with Norris and Daniil Kvyat rounding out the top 10.
Pierre Gasly struggled on the hards in the second stint and fell from seventh to P11 at the end, just ahead of the recovering Vettel.
Daniel Ricciardo spun battling Sainz (who finished 13th for McLaren) in the middle phase of the race and the Renault driver came home 14th after starting fifth.
Kevin Magnussen was a late retirement for Haas and the only non-finisher.
|1||Max Verstappen||Red Bull|
|5||Alex Albon||Red Bull||39.146|
|6||Lance Stroll||Racing Point||42.538|
|7||Nico Hulkenberg||Racing Point||55.951|
|13||Carlos Sainz Jr.||McLaren||1'14.070|
|15||Kimi Raikkonen||Alfa Romeo|
|17||Antonio Giovinazzi||Alfa Romeo|
|View full results|