The difference is that ++a is an lvalue, however a++ is not. This is specified by C++14 [expr.pre.incr]/1:
The operand of prefix ++ is modified by adding 1 [...] The
operand shall be a modifiable lvalue. [...] The result is the updated operand; it is an lvalue
and [expr.post.incr]/1:
[...] The result is a prvalue.
Now we consider auto && b = ++a; . ++a is an lvalue. auto&& is a forwarding reference. Forwarding references can actually bind to lvalues: the auto may itself deduce to a reference type. This code deduces to int &b = ++a;.
When a reference is bound to an lvalue of the same type, the reference binds directly, so b becomes another name for a.
In the second example, auto && b = a++;, a++ is a prvalue. This means it doesn't have an associated address and it's no longer any relation to the variable a. This line has the same behaviour as ++a; auto && b = (a + 0); would.
Firstly, since a++ is a prvalue, auto&& deduces to int&&. (i.e. auto deduces to int). When a reference of non-class type is bound to a prvalue, a temporary object is copy-initialized from the value. This object has its lifetime extended to match the reference.
So b in the second case is bound to a different object from a, a "temporary" int (which is not really so temporary, since it lasts as long as b does).
The reference binding rules are in [dcl.init.ref].