Hamilton overhauled poleman Bottas at Silverstone by running a longer first stint that allowed him to only stop once, and proved crucial when a safety car emerged after Bottas pit.
That gave Hamilton track advantage and he won comfortably after Bottas made a late second pitstop to use his mandatory second compound, having used mediums in his first two stints.
Charles Leclerc finished third after a dramatic fight for the final podium spot, in which Leclerc had an epic scrap with Verstappen – who was later fired into the gravel by Vettel.
Pierre Gasly scored the best result of his Red Bull career in fourth, while Verstappen managed to get his Red Bull out of the gravel and finish fifth, with Vettel down in 16th after needing a new nose and being hit with a 10-second time penalty.
Bottas led the first part of the race but kicked off the pitstops amongst the leaders while Hamilton extended his stint to lap 20. That was vital for Hamilton, who was already considering switching to the hards and executing a one-stop strategy.
He and Vettel, who struggled in the opening stint down in sixth, but also extended it, then had their persistence rewarded when the safety car emerged.
Antonio Giovinazzi locked the rear wheels on his Alfa Romeo entering the penultimate corner and slid sideways into the gravel.
With the race neutralised Hamilton and Vettel dived into the pitlane, rejoining in first and third respectively and with no further pitstops to make.
In the fight for the win, Bottas was hamstrung by the decision not to pit under the safety car and switch to hard tyres, which locked him into a two-stop strategy.
He was unable to attack Hamilton at the restart and ran a couple of seconds adrift of the Briton, before eventually pitting seven laps from the end having opened up a big enough gap to the best of the rest.
That meant he still finished second, and looked to claim the fastest lap bonus point as consolation for his lost victory – before Hamilton pumped in an even faster time on the final lap on old hards.
Hamilton’s last-gasp fastest lap meant he extended his points lead to 39.
Behind the two Mercedes drivers, Leclerc finished third after a frenzied grand prix.
Leclerc held the place early on but had to withstand enormous pressure from Verstappen, who then managed to just jump him in the pitlane as they stopped at the same time.
However, Leclerc quickly retook the place when Verstappen ran wide at The Loop immediately after exiting the pits, before falling back behind after Ferrari opted not to stop him again as soon as the safety car was deployed.
Red Bull reacted quicker and stopped Verstappen swiftly, and he rejoined fifth – behind Vettel and the sister Red Bull of Pierre Gasly, who pit earlier and stuck to a one-stop.
Ferrari’s call to stop Leclerc a lap later dropped him to sixth, and when the race resumed he attacked Verstappen immediately.
Their wheel-to-wheel fight recommenced and peaked when Leclerc attacked on the outside into the final complex of corners just before mid-distance.
They bumped wheels slightly when Leclerc had the inside for the right-hand penultimate turn, and Verstappen took to the run-off on the outside, keeping the position as he rejoined through the final corner.
Leclerc’s challenge faded after that unpenalised incident, while Verstappen passed Gasly for fourth and then caught and attacked Vettel for third.
He nailed the Ferrari on the outside at Stowe on lap 37, but ran slightly wide and Vettel tucked into his slipstream on the short run down to Vale – but positioned his Ferrari on the inside, with nowhere to go, and tried to switch back to the outside too late.
Vettel locked and slammed into the back of Verstappen’s car, pitching it airborne over a kerb and into the gravel as the Ferrari ended up facing the wrong way with its rear wheels in the gravel.
They both rejoined, but Verstappen was limited to fifth – fortunately not losing further positions – as Vettel dropped to the back.
Vettel’s elimination from the front allowed Carlos Sainz to take sixth for McLaren, fighting off Daniel Ricciardo’s Renault in a fierce best-of-the-rest fight.
Kimi Raikkonen executed a one-stop strategy to finish eighth, while Daniil Kvyat’s well-timed safety car pitstop allowed him to charge to ninth. Nico Hulkenberg completed the point scorers in 10th.
The two Haas drivers joined Giovinazzi in retirement – Romain Grosjean and Kevin Magnussen colliding on the first lap and both retiring as a result shortly afterwards.