Cain delivered run-producing singles in the first and fifth innings and he had an RBI double in the seventh. Cain's three RBIs matched a career high, accomplished twice in 2010 when he was with Milwaukee.
Cain played in only five games in April because of a torn hip flexor and groin strain.
"That's one of the main reasons we made the Melky Cabrera trade (to San Francisco) because we felt like Cain was ready to contribute," Royals manager Ned Yost said. "He is showing now exactly what we were thinking he would be capable of doing if he was healthy all year long. It's a nice shot in the arm to have him in the lineup.
"He pacing himself when he needs to and is turning it on when he needs to, but he's really swinging the bat pretty darn good," Yost added. "Honestly, he's about 85 percent."
Cain, who batted cleanup, is 13 for 31 since returning July 13.
Gordon had his 34th multihit game and is hitting .352 since moving back to the Royals leadoff spot on May 27.
Luis Mendoza (4-6) made his sixth quality start in seven appearances to collect the victory, but only his second since May 13. He yielded three runs and seven hits in 6 1/3 innings.
"He pitched into the seventh inning, did a great job again, executed his pitches," Yost said. "He battled a little bit up in the zone, but was always able to make the adjustment."
The Royals scored only one run in three of Mendoza's previous four starts, but this time they backed him with seven.
"I started up in the zone a little bit," Mendoza said. "I just tried to get some groundballs, get below. My job is to get groundballs. I just want to pitch my game, stay aggressive and try to win games."
Twins rookie left-hander Scott Diamond (8-4) lost for the first time since June 19, spanning five starts. Diamond allowed four runs and 10 hits in six innings.
"They made contact and did a good job of putting the ball in play and found holes," Twins manager Ron Gardenhire said. "I didn't think he pitched bad at all. They hit a lot of choppers and were making contact."
The Royals led off the first five innings with singles. They also hit into five double plays, four in the first five innings.
Gordon started the first inning with a single and scored on Cain's two-out single.
Jeff Francoeur and Betancourt doubled for the first Kansas City run in the eighth. Gordon singled home Betancourt for other run in the inning.
Aaron Crow worked two spotless innings to log his second save.
The Twins made it 2-all in the fourth. Ben Revere started with a triple to the right-field corner and scored on Joe Mauer's groundout. Josh Willingham, who singled, scored the other run of the inning on Chris Parmelee's fielder's choice.
The Royals took a 4-2 lead in the fifth when they were aided by an error by Parmelee at first base. Cain singled Gordon home with the first run of the inning. When Parmelee failed to handle Moustakas' hard bouncer, Alcides Escobar scored.
The Twins got a run back in the seventh when Jamey Carroll's double scored Parmelee.
With the Royals losing 14 of 18 entering Saturday, Yost called a team meeting before the game. "We just talked about a few things," Yost said. "Team meetings for me are kind of private affairs between 25 guys and the coaching staff. I'll just leave it at that." ... The Twins placed 1B Joe Morneau on the paternity list and recalled Parmelee from Triple-A Rochester. ... The Royals optioned LHP Francisley Bueno to Triple-A Omaha. ... Hosmer was dropped to the eighth slot in the Royals' batting order for the second time this season. Yost has used 11 players in the eighth hole. ... RHP Jeremy Guthrie, who was acquired in a trade Friday with Colorado, will make his first Royals start Sunday. The Twins will start rookie RHP Samuel Deduno.