Mike Morse homered for the second consecutive game and drove in three runs while Hunter Pence added three hits and scored twice for the Giants, who trailed by three runs before rallying to bail out struggling starter Matt Cain.
Cain (1-3) earned his first win of the season despite another shaky outing at AT&T Park. The former San Francisco ace gave up two home runs and allowed all the Marlins' scoring in the first three innings before settling down to pitch into the eighth.
Garrett Jones hit his sixth home run for Miami.
The Marlins had won 12 of their last 15 games at the Giants' waterfront ballpark and were comfortably ahead 4-1 before San Francisco's comeback.
Morse, who finished with three hits, cut the gap to 4-3 when he hit a two-run home run off Miami starter Nathan Eovaldi (2-2) in the third.
The Giants took the lead for good in the fifth after Angel Pagan drew a leadoff walk and Pence singled. Posey followed with his towering drive to right-center. Morse added an RBI single.
Cain stuck around after his rough start to get the win in his second outing since slicing the index finger on his right hand. He allowed six hits over 7 2-3 uneven innings, struck out seven and walked three.
Miami couldn't capitalize off the quick start and was held scoreless over the final six innings.
The Marlins announced before the game that ace Jose Fernandez will have Tommy John surgery Friday, ending the season for the reigning NL Rookie of the Year.
''Our focus is to get him back,'' manager Mike Redmond said. ''I'm glad he's having it done and starting his recovery process. Obviously it's a big blow for us.''
Giancarlo Stanton singled in the fifth to extend his 17-game hitting streak but the Marlins dropped to 2-6 on their 11-game road trip.
Cain fell behind early after giving up a solo home run to Derek Dietrich with one out in the first.
Miami added two runs in the second on Jones' two-run homer, then made it 4-1 on Casey McGehee's RBI double in the third.
Eovaldi gave up an RBI groundout to Brandon Hicks in the second then retired four straight following Morse's home run until the Giants' broke the game open in the fifth. Eovaldi allowed nine hits and six runs over 4 1-3 innings.
NOTES: Pablo Sandoval went 1 for 4 in his return to the Giants lineup after leaving Sunday's win over Atlanta with a sore toe. ... RHP Anthony DeSclafani, who made his major league debut Sunday in Fernandez's place, will remain in the Marlins' rotation for now. ... RHP Henderson Alvarez (2-3) pitches Friday and makes his second career start against the Giants. ... Tim Hudson was scheduled to pitch for San Francisco but has been scratched due to a hip strain. RHP Yusmeiro Petit (2-1) will start in Hudson's place.