Cain worked into the seventh inning Sunday in his first start against the Houston Astros since throwing a perfect game last month, and San Francisco squeezed out a 3-2 win to sweep a three-game series.
Buster Posey had three hits and two RBI, including the go-ahead single in the fifth inning.
Coming off a win as the NL's starter in the All-Star Game, Cain (10-3) gave up two runs -- one earned -- on five hits and a walk and struck out six in 6 1/3 innings.
He left with a 3-2 lead and runners on first and third base and Jeremy Affeldt got the last two outs to end the threat. Javier Lopez retired a batter in the ninth and Santiago Casilla set down the last two for his 23rd save.
It was Cain's second win in five starts since he threw the first perfect game in Giants history on June 13 against the Astros. The masterful outing included a career-high 14 strikeouts to tie Sandy Koufax's record for a perfect game.
The Giants improved to 5-7 in their last 12 games while Houston dropped to 1-13 in their last 14.
"We had to pitch well. We weren't quite swinging the bats the way we can," said Giants manager Bruce Bochy. "Buster had a nice game."
Bud Norris (5-7) lost his sixth straight start, allowing three runs on five hits and six walks in six innings. He also struck out six but remained winless since May 21.
The Giants took their 3-2 lead in the fifth inning after Pablo Sandoval led off with a double and scored on Posey's hit to center field.
Cain struck out the side in the sixth but was pulled after giving up a leadoff walk to Brian Bogusevic and a one-out single to Marwin Gonzalez in the seventh. Affeldt cleaned up, getting Brian Bixler on a pop-up and Justin Maxwell on a fly ball to end the inning.
Earlier, Gregor Blanco and Emmanuel Burriss led off with back-to-back singles to spark a two-run first inning for the Giants. After they moved up on a wild pitch, Blanco scored on Posey's base hit and Burriss later came home when Norris walked Brandon Belt with the bases loaded.
Cain retired the first six Astros in order before Gonzalez doubled to lead off the third. Gonzalez later scored on Cain's low throw to first base for an error on Jordan Schafer's bunt and the Astros tacked on a run in the fourth on Chris Johnson's RBI double to the left-center field wall, tying the game at 2-2.
The Giants are 5-1 in the season series. They are headed on a six-game road trip against the NL East starting Tuesday in Atlanta...The Astros are starting the second half with a 10-game road trip against NL West teams. It continues with four in a row at San Diego starting Monday...The Astros placed shortstop Jed Lowrie on the disabled list with a right ankle sprain after he was spiked by Blanco while covering second base on Saturday. The Astros also put catcher Jason Castro on the 15-day DL Sunday with right knee swelling. They activated the shortstop Gonzalez from the 15-day DL and recalled catcher Carlos Corporan from Triple-A Oklahoma City.
For more on the Giants, head over to McCovey Chronicles.