From man bash (as are the other quotes):
SHELL GRAMMAR
   Simple Commands
       A simple command is a sequence of optional variable assignments followed by
       blank-separated words and redirections, and terminated  by  a  control
       operator. The first word specifies the command to be executed, and is
       passed as argument zero.  The remaining words are passed as arguments
       to the invoked command.
       The return value of a simple command is its exit status, or 128+n if
       the command is terminated by signal n.
   Pipelines
       A pipeline is a sequence of one or more commands separated by one of
       the control operators | or |&.  The format for a pipeline is:
              [time [-p]] [ ! ] command [ [|⎪|&] command2 ... ]
In other words, you can have any number of redirections for a (simple) command; you can also use that as part of a pipeline. Or, put another way, redirection binds more tightly than pipe.
There are a couple of ways to get work around this (although they're rarely either necessary or aesthetic):
1. You can make a "compound command" and redirect into it:
 Compound Commands
   A compound command is one of the following:
   (list)  list is executed in a subshell environment (see
           COMMAND EXECUTION ENVIRONMENT below).  Variable
           assignments  and  builtin  commands  that  affect  the
           shell's environment do not remain in effect after the
           command completes.  The return status is the exit status of list.
   { list; }
          list  is  simply  executed  in the current shell environment.  list
          must be terminated with a newline or semicolon.  This is known as a
          group command. The return status is the exit status of list.  Note
          that unlike the metacharacters ( and ), { and } are reserved words
          and must occur where a reserved word is permitted to be recognized.
          Since they do not cause a word break, they must be separated from
          list by whitespace or another shell metacharacter.
So:
$ echo foo > input
$ { cat | sed 's/^/I saw a line: /'; } < input
I saw a line: foo
2. You can redirect to a pipe using "process substitution":
Process Substitution
   Process  substitution  is  supported on systems that support named pipes
   (FIFOs) or the /dev/fd method of naming open files.  It takes the form of
   <(list) or >(list).  The process list is run with its input or output
   connected to a FIFO or some file in /dev/fd.  The name of this file is
   passed as  an  argument  to  the  current  command  as the result of the
   expansion.  If the >(list) form is used, writing to the file will provide
   input for list.  If the <(list) form is used, the file passed as an argument
   should be read to obtain the output of list.
So:
 rici@...$ cat > >(sed 's/^/I saw a line: /') < <(echo foo; echo bar)
 I saw a line: foo
 rici@...$ I saw a line: bar
(Why the prompt appears before the output terminates, and what to do about it are left as exercises).