For value types, == and Equals() usually compare two objects by value. For example:
int x = 10;
int y = 10;
Console.WriteLine( x == y );
Console.WriteLine( x.Equals(y) );
However things are more complex for reference types. Generally speaking, for reference types == is expected to perform an identity comparison, i.e. it will only return true if both references point to the same object. By contrast, Equals() is expected to perform a value comparison, i.e. it will return true if the references point to objects that are equivalent. For example:
StringBuilder s1 = new StringBuilder("fred");
StringBuilder s2 = new StringBuilder("fred");
Console.WriteLine( s1 == s2 );
Console.WriteLine( s1.Equals(s2) );
s1 and s2 are different objects (hence == returns false), but they are equivalent (hence Equals() returns true).
Unfortunately there are exceptions to these rules. The implementation of Equals() in System.Object (the one you'll inherit by default if you write a class) compares identity, i.e. it's the same as operator==. So Equals() only tests for equivalence if the class author overrides the method (and implements it correctly). Another exception is the string class - its operator== compares value rather than identity.
Bottom line: If you want to perform an identity comparison use the ReferenceEquals() method. If you want to perform a value comparison, use Equals() but be aware that it will only work if the type has overridden the default implementation. Avoid operator== with reference types (except perhaps strings), as it's simply too ambiguous.