Mercedes used a safety car to get Bottas ahead of early race leader Vettel but the Ferrari driver used fresher, softer tyres to steal the victory with a superb move five laps from the end of the race.
Hamilton then passed teammate Bottas at the same spot a lap later to seal second and Kimi Raikkonen made it a hat-trick of late passes at Brooklands to demote his countryman from the podium entirely.
Hamilton dropped to the tail of the field at the start after Raikkonen locked his right-front tyre at the tight Turn 3 right-hander at Village, ran wide and clouted the Mercedes.
Raikkonen continued behind both Red Bulls but was handed a 10-second penalty, which would negate his on-track pass of Daniel Ricciardo into Copse, while Hamilton resumed in 17th.
Vettel had already assumed the lead after jumping Hamilton off the line and built a commanding lead in the first part of the opening stint, opening up a six-second gap over Bottas.
Hamilton charged back into the points by lap six and was into sixth four laps later, by which time he was already more than a pitstop behind the race leaders.
Bottas began to chip away at Vettel as the Ferrari struggled with its tyres and the lead was down to 4.8s when Vettel stopped on lap 20.
Bottas pit a lap later and Mercedes got Hamilton to release him with a cleanly-orchestrated position-swap at Brooklands the following lap, and the Finn started to nibble further into Vettel's lead.
He had brought it down to 2.4s when Marcus Ericsson lost the rear of his car when he turned into the first corner with DRS still open and flew across the gravel and nose-first into the tyres.
That triggered a safety car on lap 32 of 52 and Ferrari reacted by pitting Vettel but Mercedes told Bottas to stay out and claim track position.
Behind, Hamilton moved up to third as Max Verstappen and Raikkonen pit, with Ricciardo staying in sixth as the safety car was called just after he had made a second stop and handed track position to Raikkonen.
Bottas gunned the throttle at the end of the Hangar Straight on lap 37 and kept Vettel at bay, as Raikkonen and Verstappen engaged in a fierce fight that went the way of the Red Bull.
The race was neutralised again moments later for an accident at Copse between Carlos Sainz and Romain Grosjean, when Sainz attacked on the outside but Grosjean suffered a wobble at the apex.
Both flew off-track and into retirement, with Grosjean ending a miserable race that started with him dropping out of the points on the opening lap thanks to a collision with teammate Kevin Magnussen.
The safety car's second appearance lasted three laps, setting up an 11-lap sprint at the end.
Bottas resisted Vettel again at the restart before coming under attack from Vettel into the Brooklands left-hander at the end of the Wellington Straight three laps in row.
He held on until lap 47, when Vettel took advantage of a slight wobble from Bottas exiting The Loop onto the Wellington Straight and drafted him towards Brooklands before diving inside very late as Bottas failed to cover the inside line.
That released Vettel into a lead he would hold comfortably to the end, while Hamilton forced his way inside Bottas at Brooklands a lap later.
Raikkonen cleared Verstappen before the Dutchman retired with a long-standing brake-by-wire problem then blew past Bottas for third on the outside into Brooklands using DRS.
Bottas managed to keep Ricciardo at bay to finish fourth, with Nico Hulkenberg finished sixth for Renault after taking advantage of the messy first lap to jump five places, and he held that best-of-the-rest slot to the end.
Force India's Esteban Ocon was a quiet but excellent seventh, as Fernando Alonso bested Magnussen in a fiery late fight to finish eighth.
Pierre Gasly claimed the final point in 10th for Toro Rosso and Honda.
1 | 5 | Sebastian Vettel | FERRARI | 52 | 1:27:29.784 | 25 |
2 | 44 | Lewis Hamilton | MERCEDES | 52 | +2.264s | 18 |
3 | 7 | Kimi Räikkönen | FERRARI | 52 | +3.652s | 15 |
4 | 77 | Valtteri Bottas | MERCEDES | 52 | +8.883s | 12 |
5 | 3 | Daniel Ricciardo | RED BULL RACING TAG HEUER | 52 | +9.500s | 10 |
6 | 27 | Nico Hulkenberg | RENAULT | 52 | +28.220s | 8 |
7 | 31 | Esteban Ocon | FORCE INDIA MERCEDES | 52 | +29.930s | 6 |
8 | 14 | Fernando Alonso | MCLAREN RENAULT | 52 | +31.115s | 4 |
9 | 20 | Kevin Magnussen | HAAS FERRARI | 52 | +33.188s | 2 |
10 | 11 | Sergio Perez | FORCE INDIA MERCEDES | 52 | +34.708s | 0 |
11 | 2 | Stoffel Vandoorne | MCLAREN RENAULT | 52 | +35.774s | 0 |
12 | 18 | Lance Stroll | WILLIAMS MERCEDES | 52 | +38.106s | 0 |
13 | 10 | Pierre Gasly | SCUDERIA TORO ROSSO HONDA | 52 | +39.129s | 0 |
14 | 35 | Sergey Sirotkin | WILLIAMS MERCEDES | 52 | +48.113s | 0 |
15 | 33 | Max Verstappen | RED BULL RACING TAG HEUER | 46 | DNF | 0 |
NC | 8 | Romain Grosjean | HAAS FERRARI | 37 | DNF | 0 |
NC | 55 | Carlos Sainz | RENAULT | 37 | DNF | 0 |
NC | 9 | Marcus Ericsson | SAUBER FERRARI | 31 | DNF | 0 |
NC | 16 | Charles Leclerc | SAUBER FERRARI | 18 | DNF | 0 |
NC | 28 | Brendon Hartley | SCUDERIA TORO ROSSO HONDA | 1 | DNF | 0 |
Note - Raikkonen received a 10-second penalty for causing a collision. Gasly originally finished 10th but received a 5-second penalty for causing a collision.
1 | FERRARI | 287 |
2 | MERCEDES | 267 |
3 | RED BULL RACING TAG HEUER | 199 |
4 | RENAULT | 70 |
5 | HAAS FERRARI | 51 |
6 | FORCE INDIA MERCEDES | 49 |
7 | MCLAREN RENAULT | 48 |
8 | SCUDERIA TORO ROSSO HONDA | 19 |
9 | SAUBER FERRARI | 16 |
10 | WILLIAMS MERCEDES | 4 |
1 | Sebastian Vettel | GER | FERRARI | 171 |
2 | Lewis Hamilton | GBR | MERCEDES | 163 |
3 | Kimi Räikkönen | FIN | FERRARI | 116 |
4 | Daniel Ricciardo | AUS | RED BULL RACING TAG HEUER | 106 |
5 | Valtteri Bottas | FIN | MERCEDES | 104 |
6 | Max Verstappen | NED | RED BULL RACING TAG HEUER | 93 |
7 | Nico Hulkenberg | GER | RENAULT | 42 |
8 | Fernando Alonso | ESP | MCLAREN RENAULT | 40 |
9 | Kevin Magnussen | DEN | HAAS FERRARI | 39 |
10 | Carlos Sainz | ESP | RENAULT | 28 |
11 | Esteban Ocon | FRA | FORCE INDIA MERCEDES | 25 |
12 | Sergio Perez | MEX | FORCE INDIA MERCEDES | 24 |
13 | Pierre Gasly | FRA | SCUDERIA TORO ROSSO HONDA | 18 |
14 | Charles Leclerc | MON | SAUBER FERRARI | 13 |
15 | Romain Grosjean | FRA | HAAS FERRARI | 12 |
16 | Stoffel Vandoorne | BEL | MCLAREN RENAULT | 8 |
17 | Lance Stroll | CAN | WILLIAMS MERCEDES | 4 |
18 | Marcus Ericsson | SWE | SAUBER FERRARI | 3 |
19 | Brendon Hartley | NZL | SCUDERIA TORO ROSSO HONDA | 1 |
20 | Sergey Sirotkin | RUS | WILLIAMS MERCEDES | 0 |