Basic GIF example
Using the reverse and concat filters:
ffmpeg -i input.mp4 -filter_complex "[0]reverse[r];[0][r]concat=n=2:v=1:a=0" output.gif
GIF from ffmpeg
will loop forever by default, so you don't need to add any loop options.
High quality GIF example
Using the reverse, concat, split, palettegen, and paletteuse filters:
ffmpeg -i input.mp4 -filter_complex "[0]reverse[r];[0][r]concat=n=2:v=1:a=0,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif
Adapted from How do I convert a video to GIF using ffmpeg, with reasonable quality?
With downscaling and lower frame rate for smaller file size
Same as above but with the scale and fps filters added:
ffmpeg -i input.mp4 -filter_complex "[0]scale=320:-1,reverse[r];[0][r]concat=n=2:v=1:a=0,fps=10,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif
Avoid duplicating first and last frames
By adding the trim and setpts filters. In this example input.mp4
has a frame rate of 10 and is 3 seconds long. Note that in the trim filter frame #0 is the first frame.
ffmpeg -i input.mp4 -filter_complex "[0]trim=start_frame=1:end_frame=29,setpts=PTS-STARTPTS,reverse[r];[0][r]concat=n=2:v=1:a=0,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif
Also see Fetch frame count with ffmpeg.