Index: src/wp-includes/deprecated.php
===================================================================
--- src/wp-includes/deprecated.php	(revision 28709)
+++ src/wp-includes/deprecated.php	(working copy)
@@ -3459,6 +3459,21 @@
 }
 
 /**
+ * Formerly used to escape strings before searching the DB. It was poorly documented and never worked as described.
+ *
+ * @since 2.5.0
+ * @deprecated 4.0.0
+ * @deprecated Use wpdb::esc_like()
+ *
+ * @param string $text The text to be escaped.
+ * @return string text, safe for inclusion in LIKE query.
+ */
+function like_escape($text) {
+	_deprecated_function( __FUNCTION__, '4.0', 'wpdb::esc_like()' );
+	return str_replace(array("%", "_"), array("\\%", "\\_"), $text);
+}
+
+/**
  * Determines if the URL can be accessed over SSL.
  *
  * Determines if the URL can be accessed over SSL by using the WordPress HTTP API to access
Index: src/wp-includes/formatting.php
===================================================================
--- src/wp-includes/formatting.php	(revision 28709)
+++ src/wp-includes/formatting.php	(working copy)
@@ -3100,18 +3100,6 @@
 }
 
 /**
- * Escapes text for SQL LIKE special characters % and _.
- *
- * @since 2.5.0
- *
- * @param string $text The text to be escaped.
- * @return string text, safe for inclusion in LIKE query.
- */
-function like_escape($text) {
-	return str_replace(array("%", "_"), array("\\%", "\\_"), $text);
-}
-
-/**
  * Convert full URL paths to absolute paths.
  *
  * Removes the http or https protocols and the domain. Keeps the path '/' at the
Index: src/wp-includes/wp-db.php
===================================================================
--- src/wp-includes/wp-db.php	(revision 28709)
+++ src/wp-includes/wp-db.php	(working copy)
@@ -1169,6 +1169,29 @@
 	}
 
 	/**
+	 * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
+	 *
+	 * Use this only before wpdb::prepare() or esc_sql().  Reversing the order is very bad for security.
+	 *
+	 * Example Prepared Statement:
+	 *  $wild = '%';
+	 *  $find = 'only 43% of planets';
+	 *  $like = $wild . $wpdb->esc_like( $find ) . $wild;
+	 *  $sql  = $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE post_content LIKE %s", $like );
+	 *
+	 * Example Escape Chain:
+	 *  $sql  = esc_sql( $wpdb->esc_like( $input ) );
+	 *
+	 * @since 4.0.0
+	 *
+	 * @param string $text The raw text to be escaped. The input typed by the user should have no extra or deleted slashes.
+	 * @return string Text in the form of a LIKE phrase. The output is not SQL safe. Call prepare or real_escape next.
+	 */
+	function esc_like($text) {
+		return addcslashes( $text, '_%\\' );
+	}
+
+	/**
 	 * Print SQL/DB error.
 	 *
 	 * @since 0.71
Index: tests/phpunit/tests/db.php
===================================================================
--- tests/phpunit/tests/db.php	(revision 28709)
+++ tests/phpunit/tests/db.php	(working copy)
@@ -105,10 +105,109 @@
 			} else {
 				setlocale( LC_ALL, $locale_setting );
 			}
+	}
+
+	/**
+	 * @ticket 10041
+	 */
+	function test_esc_like() {
+		global $wpdb;
+
+		$inputs = array(
+			'howdy%', //Single Percent
+			'howdy_', //Single Underscore
+			'howdy\\', //Single slash
+			'howdy\\howdy%howdy_', //The works
+			'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?', //Plain text
+		);
+		$expected = array(
+			'howdy\\%',
+			'howdy\\_',
+			'howdy\\\\',
+			'howdy\\\\howdy\\%howdy\\_',
+			'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?',
+		);
+
+		foreach ($inputs as $key => $input) {
+			$this->assertEquals($expected[$key], $wpdb->esc_like($input));
 		}
 	}
 
 	/**
+	 * Test LIKE Queries
+	 *
+	 * Make sure $wpdb is fully compatible with esc_like() by testing the identity of various strings.
+	 * When escaped properly, a string literal is always LIKE itself (1)
+	 * and never LIKE any other string literal (0) no matter how crazy the SQL looks.
+	 *
+	 * @ticket 10041
+	 * @dataProvider data_like_query
+	 * @param $data string The haystack, raw.
+	 * @param $like string The like phrase, raw.
+         * @param $result string The expected comparison result; '1' = true, '0' = false
+	 */
+	function test_like_query( $data, $like, $result ) {
+		global $wpdb;
+		return $this->assertEquals( $result, $wpdb->get_var( $wpdb->prepare( "SELECT %s LIKE %s", $data, $wpdb->esc_like( $like ) ) ) );
+	}
+
+	function data_like_query() {
+		return array(
+			array(
+				'aaa',
+				'aaa',
+				'1',
+			),
+			array(
+				'a\\aa', // SELECT 'a\\aa'  # This represents a\aa in both languages.
+				'a\\aa', // LIKE 'a\\\\aa'
+				'1',
+			),
+			array(
+				'a%aa',
+				'a%aa',
+				'1',
+			),
+			array(
+				'aaaa',
+				'a%aa',
+				'0',
+			),
+			array(
+				'a\\%aa', // SELECT 'a\\%aa'
+				'a\\%aa', // LIKE 'a\\\\\\%aa' # The PHP literal would be "LIKE 'a\\\\\\\\\\\\%aa'".  This is why we need reliable escape functions!
+				'1',
+			),
+			array(
+				'a%aa',
+				'a\\%aa',
+				'0',
+			),
+			array(
+				'a\\%aa',
+				'a%aa',
+				'0',
+			),
+			array(
+				'a_aa',
+				'a_aa',
+				'1',
+			),
+			array(
+				'aaaa',
+				'a_aa',
+				'0',
+			),
+			array(
+				'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?',
+				'howdy\'"[[]*#[^howdy]!+)(*&$#@!~|}{=--`/.,<>?',
+				'1',
+			),
+		);
+		}
+	}
+
+	/**
 	 * @ticket 18510
 	 */
 	function test_wpdb_supposedly_protected_properties() {
Index: tests/phpunit/tests/formatting/LikeEscape.php
===================================================================
--- tests/phpunit/tests/formatting/LikeEscape.php	(revision 28709)
+++ tests/phpunit/tests/formatting/LikeEscape.php	(working copy)
@@ -1,29 +0,0 @@
-<?php
-
-/**
- * @group formatting
- */
-class Tests_Formatting_LikeEscape extends WP_UnitTestCase {
-	/**
-	 * @ticket 10041
-	 */
-	function test_like_escape() {
-
-		$inputs = array(
-			'howdy%', //Single Percent
-			'howdy_', //Single Underscore
-			'howdy\\', //Single slash
-			'howdy\\howdy%howdy_', //The works
-		);
-		$expected = array(
-			"howdy\\%",
-			'howdy\\_',
-			'howdy\\\\',
-			'howdy\\\\howdy\\%howdy\\_'
-		);
-
-		foreach ($inputs as $key => $input) {
-			$this->assertEquals($expected[$key], like_escape($input));
-		}
-	}
-}
