First of all, an "lvalue" is an expression that is legal on the left side (the "l" in "lvalue") of an assignment. That means it represents an address whose contents can be changed by the assignment. (The C standard calls such a thing an "object".) That's why, e.g., infix operator expressions and function calls aren't lvalues.
"rvalue" is a silly term; any well-formed expression is legal on the right side of an assignment (setting aside type conversion issues).
The standard says that, e.g.:
i = ++i + 1;
a[i++] = i;
..are both "undefined statement expressions", meaning their implementation (and therefore behavior) is not standardized.
The common sense meaning of "++i" is "increment the value of the object i, and evaluate to the result". Similarly, "i++" means "evaluate to the current value of the object i, and increment the object's value afterward". Neither says what happens when "++i" or "i++" is used as an lvalue.
The standard says, about expressions: "The value computations of the operands of an operator are sequenced before the value computation of the result of the operator." This is actually ambiguous for "++i", since the value computation of the operand is affected by the value computation of the operator.
What makes the most sense to me is this:
i = 5;
++i = i + 1; /*i is set to 6*/
i++ = 1; /*i is set to 1*/
++i = ++i + 1; /*i is set to 8, but problematic*/
i++ = i++ + 1; /*i is set to 8, but problematic*/
++i = i++ + 1; /*i is set to 8, but problematic*/
My advice -- don't use expressions that are so hard to understand!