A superb Ronaldo 25-yard free-kick had Portugal ahead in the 25th minute, though Switzerland went close through striker Haris Seferovic either side of the opener.
But the Swiss were level in controversial fashion as they were initially denied a penalty before Portugal went up the other end and instantly won a penalty of their own through Bernardo Silva.
But, after a VAR check, the initial Swiss penalty appeal was given by VAR for a tug from Nelson Semedo on Steven Zuber, allowing Ricardo Rodriguez to tuck away the penalty in the 57th minute.
Switzerland threatened to grab a winner, but it was Portuguese legend Ronaldo who won it, putting the hosts back ahead with a low, first-time finish in the 88th minute, before cutting in to find the bottom corner in the 90th.
Portugal will now play in Sunday’s final against the winners of England’s clash with the Netherlands, who play on Thursday night.