I could find a few bits off code on Google by searching for "normalize email address", but nothing nearly thorough enough. I'm afraid you would have to write your own tool. If I were to write such a tool, here are a few rules I think I would apply:
First the tool would lower the case of the domain name (after the @). It shouldn't be too hard, unless you want to handle emails with international domain names. For example, JoE@caFÉ.fR (note the accent on the E) should first go through the Nameprep algorithm. This leads to JoE@xn--caf-dma.fr. I have never seen anyone with such an international email address, but I suspect you might find some in China or Japan, for example.
RFC 5322 states that the local-part of the email (before the @) is case sensitive, but the de facto standard for virtually all providers is to ignore case (I have never seen a case-sensitive email address actually used by a human being, but I suppose there are still some sysadmins out there who use their Un*x email accounts, where case does matter). I think the tool should have an option to ignore case for a list of domain names (or on the contrary, to be case sensitive only for a list of domain names). So at this point, the email address JoE@caFÉ.fR is now normalized to joe@xn--caf-dma.fr.
Once again, the question of international (aka. non ASCII) email addresses pops up. What if the local-part is non-ASCII ? For example something like 甲斐@黒川.日本 (disclaimer: I don't speak Japanese). RFC 5322 forbids this, but more recent RFCs do support this (see this wikipedia article). A lot of languages have no notion of lower or uppercase. When they do, if you want to change to the lower-case form, make sure to use the appropriate Unicode lower-case algorithms, it's not always trivial. For example, in German, the lower case of the word "Großes" may be either "grosses" or "großes" (disclaimer: I don't speak German either). So at this point, the email address "Großes@caFÉ.Fr" should have been normalized to "grosses@xn--caf-dma.fr".
I haven't read RFC 5322 in detail but I think there's also a possibility to have comments in an email address, either at the beginning or at the end of the local part, such as (sir)john.lennon@beatles.com or john.lennon(ono)@beatles.com. These comments should be stripped (this would lead to john.lennon@beatles.com. Stripping the comments is not entirely trivial because I don't know what to do with the nested comments, and also comments enclosed in double-quotes should not be stripped, according to the RFC (unless I am mistaken). For example, the comment in the following email address should not be stripped, according to the RFC: "john.(ono).lennon"@beatles.com.
Once the email is thus normalized, I would apply the "provider-specific" rules you suggest. For example stripping the dots in GMail addresses and mixing equivalent domain names (googlemail.com == gmail.com for example). I think I would keep this really separate from the previous normalization steps.
Note that Gmail also ignores the plus sign (+) and everything after it, for example s.m.i.t.h+hello_world@gmail.com is equivalent to smith@gmail.com.
I'm not aware of other provider rules. The thing is, these rules may change at any time, you would have to keep track of them all.
I think that's about it. If you come up with some working code, I would be really interested to see it.
Cheers!