Paulinho scored with a header four minutes from time to give Brazil a 2-1 win over Uruguay and take the host nation to the final of the Confederations Cup.
Diego Forlan missed a penalty in the 13th minute after Chelsea defender David Luiz wrestled Diego Lugano to the ground. Brazil took the lead in the 40th minute when Neymar latched onto to a long ball from Paulinho and his deflected shot fell to Fred, who bundled the ball home.
It took Uruguay three minutes of the second half to draw level.
The Brazilian defence repeatedly failed to clear the ball and when Thiago Silva's weak pass fell to Edinson Cavani he made no mistake with an angled drive.
The second half threw up few good chances but Paulinho rose to head home a Neymar corner in the 86th minute and give Brazil victory, with Spain and Italy playing in Thursday's second semi.
The final of the World Cup warm-up is at Rio de Janeiro's Maracana on Sunday.
Brazil made one change from the team that beat Italy in their last group game, bringing Paulinho in to replace Hernanes in midfield.
Uruguay left out Abel Hernandez, the young Palermo forward who scored four goals against Tahiti in midweek, and opted instead for their big name front line of Luis Suarez, Diego Forlan, and Edinson Cavani.
Uruguay knew Brazil would come at them straight from the kick off and they took the sting out their opponents by slowing the game right down.
Both sides looked nervous and the early moments were tense, with neither side able to string any passes together.
It was a pattern repeated throughout a match marked by a lack of fluid play or individual brilliance.
Uruguay's front three failed to get the better of Brazil's back line and Neymar was a shadow of the player who won the man of the match award in his last three games.
The win was Brazil's fourth in four games at this year's tournament and their fifth in a row under Luiz Felipe Scolari, a run that belies their 22nd place in the FIFA rankings, their lowest ever.
It also extends their unbeaten run over their South American rivals to eight games dating back to July 2001.