1924年冬天,9岁的小豆子被当妓女的母亲切掉左手上那根畸形的指头后进入关家戏班学戏。戏班里只有师兄小石头同情关照小豆子。十年过去了,在关师父严厉和残酷的训导下,师兄二人演技很快提高,小豆子取艺名程蝶衣(张国荣饰),演旦角;小石头取艺名段小楼(张丰毅饰),演生角。俩人合演的《霸王别姬》誉满京城,师兄弟二人也红极一时。蝶衣希望和段合演一辈子《霸王别姬》。
段小楼娶妓女菊仙(巩俐饰)为妻,依恋着师兄的蝶衣,心情沉重地来到师兄住处,把他用屈辱换来的、师兄向往已久的名贵宝剑赠给小楼,并决定不再与小楼合演《霸王别姬》。在关师傅的召唤下,师兄弟二人再次合作。
抗战结束后,两人被迫给一群无纪律无素质的国军士兵唱戏,段小楼与士兵冲突,混乱中菊仙流产,而后有士兵以汉奸罪抓走蝶衣。段小楼倾力营救蝶衣,低声下气去求曾经玩弄蝶衣的官僚袁世卿(葛优饰)。菊仙要蝶衣说谎苟且求释,并将小楼不再与蝶衣唱戏的字据给蝶衣看。于是蝶衣在法庭上始终不屈,却因其技艺被国民党高官营救。解放后,两人的绝艺并没有受到重视,误尝鸦片的程蝶衣嗓音日差,在一次表演中破嗓,决心戒毒,历经毒瘾折磨后在段小楼夫妻的共同帮助下终于重新振作,却被当年好心收养的孩子小四陷害,小四逼着要取代他虞姬的位置与段小楼演出,段小楼不顾后果罢演,菊仙为了大局劝他演,段小楼最终进行了演出。蝶衣伤心欲绝,从此与段小楼断交。
文化大革命时,段小楼被小四陷害,并逼他诬陷蝶衣,段小楼不肯,被拉去游街,此时蝶衣却突然出现,一身虞姬装扮,甘愿同段小楼一起受辱,段小楼见蝶衣已经自投陷阱,希望能保护菊仙而在无奈中诬陷蝶衣,甚至说他是汉奸,蝶衣听后痛不欲生,以为段小楼只在乎菊仙,又看到自己所怨恨的菊仙此刻竟在可怜自己、帮助自己,便将所有的愤懑发泄在菊仙身上,抖出菊仙曾为娼妓,段小楼因此被逼与菊仙划清界线,说从来没爱过菊仙,菊仙在绝望中上吊自杀。
打倒“四人帮”后,师兄二人在分离了11年的舞台上最后一次合演《霸王别姬》,师哥段小楼引出了程蝶衣说出了那句“我本是男儿郎,又不是女娇娥”,蝶衣这才意识到自己其实是男儿身,终于明白了自己一直都活在了戏中。