Bottas eventually came home third behind Hamilton, therefore claiming the first podium of his Formula One career, while Massa held on to fourth ahead of Ferrari's Fernando Alonso.
It was Massa who seized the initiative at the start, leading from pole as fellow front-row starter Bottas lost out to Rosberg away from the line and then snatched back second heading down to Turn 2.
Hamilton meanwhile made a superb start, shooting between Ferrari's Kimi Raikkonen and Toro Rosso's Daniil Kvyat off the line to claim seventh, picking off Red Bull's Daniel Ricciardo and McLaren's Kevin Magnussen before Turn 2, and then diving down the inside of Alonso at Turn 8 to complete a stunning first lap in fourth place.
There then followed a lengthy game of nip and tuck between Williams and Mercedes at the front of the race, with Bottas and Massa appearing to give nothing away to the Mercedes on the supersoft Pirelli tyres. Indeed it was Rosberg and Hamilton who switched sooner to the softs, on laps 11 and 13, before Massa and Bottas did likewise on 14 and 15 respectively.
That left Sergio Perez, who started from 15th on the softs, in the lead for Force India, and he held Rosberg at bay until the 26th lap - the German having undercut Bottas in the stops. For a while the championship leader had Bottas and Hamilton in his wheeltracks, but once past Perez he was able to pull away again. Massa, meanwhile, had dropped to fourth, chased by Alonso.
Hamilton stopped again for fresh softs on lap 39, Rosberg on 40 and Bottas on 41, and a fastest lap on lap 41 put Hamilton into second place.
For the rest of the race it was a straight battle between the two Mercedes drivers. Both were having to manage their brakes, and perhaps Hamilton suffered with that more as the gap fluctuated but rarely extended past two seconds.
He kept pushing, however, and they went into the last lap within a second of each other, both authorised to use the overtake button. When Rosberg locked up his right front momentarily and ran wide at Turn 3 it seemed that Hamilton might have his chance, but as the German recovered the Englishman had run out of opportunities and backed off in the final sector to finish 1.9s behind.
That, however, amounted to the difference in their respective pit stop times...
Bottas drove a superb race to convert second on the grid into a first podium, with Williams adding 27 points to their tally thanks also to Massa fending off Alonso's late attack.
Perez fought back from a late second pit stop, making the most of his supersofts to displace Kevin Magnussen's McLaren and jump back up to a sixth place - a result that did his reputation a lot of good after Canada.
In a race sponsored by Red Bull and run at the energy drinks company's own venue, both Red Bull and Toro Rosso had hideous days. Sebastian Vettel was in trouble right from the start with the loss of drive that would ultimately cause him to retire, while both Kvyat and Jean-Eric Vergne joined him, the only three retirements of the race.
The sole bright spot was Daniel Ricciardo's fighting eighth, after he overtook Nico Hulkenberg's Force India on the last lap.
As Jenson Button's late second stop in the McLaren dropped him to 11th, Kimi Raikkonen took the final point for Ferrari.
Pastor Maldonado was 12th for Lotus ahead of Adrian Sutil's Sauber, team mate Romain Grosjean, Jules Bianchi's Marussia, Kamui Kobayashi's troubled Caterham, Max Chilton's Marussia, Marcus Ericsson's Caterham and Esteban Gutierrez's Sauber.
Rosberg's victory opens his lead to 29 points over Hamilton, 165 to 136, with Ricciardo hanging on to third with 83 from Alonso on 79, Vettel on 60, Hulkenberg on 59 and Bottas on 55.
In the constructors' stakes, Mercedes have 301 points, Red Bull 143, Ferrari 98, Force India 87, Williams 85 and McLaren 72.