Q:

prOGraMMIng PuZZleS & cOde ____

Input
A non-empty encoded string consisting of printable ASCII characters (in the range 32-126), where some missing letters have been replaced with _.
Output
A decoded string of the same length with all letters in lowercase, including the missing ones.
How?
Edit: As mentioned by @Deusovi in the comments, this is a variant of Bacon's cipher.

Gather all letters in the original string and group them by 5. Additional letters that do not fit in a full group of 5 are ignored.
Convert each group into binary: lowercase = 0, uppercase = 1. This leads to a list of integers.
Use each value N in this list to replace each _ in the original string with the N-th letter of the alphabet (0-indexed), in order of appearance.

Example: prOGraMMIng PuZZleS & cOde ____
prOGr --> 00110 -->  6 -->  7th letter = 'g'
aMMIn --> 01110 --> 14 --> 15th letter = 'o'
gPuZZ --> 01011 --> 11 --> 12th letter = 'l'
leScO --> 00101 -->  5 -->  6th letter = 'f'

By replacing the missing letters and converting everything back to lowercase, the original string is unveiled:
programming puzzles & code golf

This is the expected output.
Clarifications and rules

The missing letters are guaranteed to appear at the end of the string. More formally: there will never be any letter after the first _ in the input string. However, there may be other printable ASCII characters such as spaces and punctuation marks.
The input is guaranteed not to contain any useless capital letter: all capital letters are bits set to 1 which are required to decode the missing letters. Everything else is in lowercase.
The input string is guaranteed to be valid. Especially:

It will always contain enough full groups of 5 letters to decode the underscores.
The binary-encoded integers are guaranteed to be in the range [0-25].

There may be no _ at all in the input string, in which case you just have to return the input.
This is code-golf, so the shortest answer in bytes wins!

Test cases
Input : hello!
Output: hello!

Input : helLO, worl_!
Output: hello, world!

Input : i aM yoUr faTh__.
Output: i am your father.

Input : prOGraMMIng PuZZleS & cOde ____
Output: programming puzzles & code golf

Input : Can YOu gUesS tHE ENd oF This ____?
Output: can you guess the end of this text?

Input : THe qUICk brown FOx JUMps oVEr the la__ ___.
Output: the quick brown fox jumps over the lazy dog.

Input : RoadS? wHERe we're goinG WE doN't need _____.
Output: roads? where we're going we don't need roads.

Input : thE greatESt Trick thE DeVIl EVer PUllEd wAs CONvInciNg tHe WorLD h_ ____'_ _____.
Output: the greatest trick the devil ever pulled was convincing the world he didn't exist.

Some extra test-cases:
Input : BInar_
Output: binary

Input : 12 MonKey_
Output: 12 monkeys

Input : hyPerbolIZ__
Output: hyperbolized

Input : {[One Last Test ca__]}
Output: {[one last test case]}

A:

05AB1E, 18 bytes
Code:
áS.u5ôJC>.bv'_y.;l

Uses the 05AB1E encoding. Try it online!
Explanation:
á                       # Remove non-letters from the input string.
 S                      # Split the result into individual characters.
  .u                    # Check if is uppercase for each character.
    5ôJ                 # Split into binary numbers of length 5.
       C                # Convert from binary to decimal.
        >               # Add one.
         .b             # Map 1 → A, 2 → B, 3 → C, ..., 25 → Y, 26 → Z.
           v            # For each letter:
            '_y.;       #   Replace the first occurrence of '_' with the current letter.
                 l      #   Convert the string to lowercase.

A:

Perl 5 -pF -MList::Util=sum, 75 bytes
@a=grep!/\W|\d/,@F;s!_!(a..z)[sum map{a gt shift@a&&16/2**$_}0..4]!eg;$_=lc

Try it online!
Explanation:

-pF reads a line of input into the variable $_ and, split into characters, into the array @F.
@a=grep!/\W|\d/,@F sets the array @a equal to those members of @F that don't satisfy the regex \W|\d. \W is anything but letters, numbers, and _; \d is numbers. So \W|\d is anything but letters and _, and @a has all the letters and _ characters. We will wind up never examining the _ characters in @a. (Note that this only works because the input is guaranteed ASCII.)
map{a gt shift@a&&16/2**$_}0..4 does the following for 0 through 4: It shifts the next element off of @a, shortening it, and evaluates whether a is asciibetically greater than that element (i.e. whether that element is uppercase). If so, && isn't short-circuited, so we get 16 divided by 2 to rhe power of the input value (0 through 4). Otherwise && is short-circuited and we get 0. map returns the list of five numbers to sum, which adds them.
That's the element we want from the list a..z, and that's what we get from (a..z)[…].
s!_!…!eg converts each _ in $_, in turn, to the appropriate letter.
$_=lc converts $_ to the lowercase version of itself, and -p prints it.

A:

Python 2, 113 bytes
s=input()
i=k=0
for c in s:
 if c.isalpha():k+=k+(c<'a');i+=1;s=s.replace('_',chr(k%32+97),i%5<1)
print s.lower()

Try it online!

