Pipes can be thought of as a tube where data enters one end and sorted or customized at the other end.  Using pipes you can connect two programs. You can make the output of a particular command to act as the input for another command.  You can carry on this chain  between commands for customized outputs.

Pipes can be used with most of the Unix commands. You should take care to check that the output of the first command is acceptable input to the second command.
It should not be that the first command has its output in some format other than text format and the second command works with only text input. If at all this sort of thing happens, you would mostly get an error message or you would have to type <Ctrl>-C to quit the execution of the command and come back to the prompt.

This is best explained using an example

$ ls | grep 'mp3'
This command basically consists of 2 commands joined by a pipe. The first command gets the listing of the current directory and then pipes it to (sends it to) the second command which is a grep command. The grep command selects those lines from the directory listing (which it received from the ls command) having the string 'mp3' in them. So basically as a result of this command you would get a list of files / directories that have the letters 'mp3' in their names.
You might think this is not really useful, when you could have used some form of ls command itself (probably shorter) to get the some work done. The use of pipes becomes evident as you design more complex commands.

Take the following command. This one too is simple, but you would get the idea behind pipes.

$ ls | grep 'mp3' | sort -r
This command would do the same as the above one, but this time instead of displaying all the files/directories having the string 'mp3' in their names, this result is passed on to the sort command through a pipe. The sort command with the -r option sorts this result in the reverse order. And then finally displays the result.