The Tykes twice hit back from two goals down and were ultimately undone by a second-half penalty that resulted in defender Ryan Shotton's dismissal.
Nicky Maynard fired his ninth goal of the season to give City a 26th-minute lead and then on-loan Ajax midfielder Evander Sno hit his first for the club just before the interval.
Tykes substitute Daniel Bogdanovic hauled Robins' side back into it just after the hour mark before Shotton was deemed to have penalised Danny Haynes in the penalty area in the 73rd minute.
Home goalkeeper Luke Steele pulled off a fine save to keep out Jamie McAllister's spot-kick, but Marvin Elliott followed up to bury the rebound and although Adam Hammill fired a second for Barnsley in injury time, City extended their unbeaten run to five matches.
Robins said: "We started brightly and had the better of the early exchanges. That was a game we could and should have won. We just looked lacklustre.
That's two defeats on the bounce and we don't like losing two games on the bounce.
City boss Gary Johnson said: "I'm very pleased, it's a difficult place to come to and win. I thought our lads played well.
"We were playing well at 2-0 up and then the goalkeeper (Dean Gerken) let one go through his legs.
I am not going to blame the 'keeper because he made a marvellous save in the final five minutes.
He added: "It's great getting three points and scoring three goals away from home.
"It's a fantastic win. It was a good goal from Nicky and at 2-0 it was quite comfortable and we had to make sure that we didn't give them a goal.
"The league is very tight and if we perform we can get a lot of wins."