Second-ranked Federer came from behind to beat Argentine Juan Martin del Potro 3-6, 6-3, 6-3 to ensure he would meet Nadal for the fourth time this year in Sunday's final.
Nadal leads the head-to-head with Federer 23-14 but has not beaten the Swiss in 2017, losing in the finals of the Australian Open and Miami Masters and in the last-16 at Indian Wells.
The Spaniard was pushed hard by fourth seed Cilic, who put his booming forehand to good use but could not stop Nadal claiming a 16th consecutive victory.