The general form for binding identifier values in F# is
let pattern = expression
In this case, the pattern is "line1, line2", which is a tuple pattern, it will expect to bind to a 2-tuple of values and assign the names "line1" and "line2" to those two values.
The expression is the next 4 lines. Inside that expression there are local variables. They happen to also be named "line1" and "line2", but they could easily have been renamed "x" and "y" or whatever - the scope of those identifiers is local to this indented expression. (The fact that the same names are used as the names in the outer scope has no effect as far as the compiler is concerned.)
The final line if the expression is the 'return value' of the expression. In this case it returns the 2-tuple of values "line1" and "line2" (or "x" and "y" if you rename them for clarity of exposition). Incidentally, since these two values each have type "string", the type of the return expression is "string*string", which is a 2-tuple where each value is a string. This means the original "line1" and "line2" names on the first line will each be inferred to have type "string".
F# is functional, and so in a sense "everything is an expression" and "there are no statements" (only sequences of expressions that are sequentially evaluated), but it is ok IMO to (ab)use the term "statement" to describe the inner "let" lines, unless you're trying to be very precise.