diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
index 47633d1..dbaee41 100644
--- src/wp-includes/taxonomy.php
+++ src/wp-includes/taxonomy.php
@@ -2485,12 +2485,29 @@ function wp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) {
 		if ( !strlen(trim($term)) )
 			continue;
 
-		if ( !$term_info = term_exists($term, $taxonomy) ) {
-			// Skip if a non-existent term ID is passed.
-			if ( is_int($term) )
+		if ( is_int( $term ) ) {
+			if ( ! $term_info = term_exists( $term, $taxonomy ) ) {
 				continue;
-			$term_info = wp_insert_term($term, $taxonomy);
+			}
+		} else {
+			// Give preference to slug.
+			$found_term = get_term_by( 'slug', $term, $taxonomy );
+			print_r( $found_term );
+			if ( ! $found_term ) {
+				$found_term = get_term_by( 'name', $term, $taxonomy );
+			}
+
+			if ( $found_term ) {
+				// For legacy purposes, these values should be numeric strings.
+				$term_info = array(
+					'term_id' => (string) $found_term->term_id,
+					'term_taxonomy_id' => (string) $found_term->term_taxonomy_id,
+				);
+			} else {
+				$term_info = wp_insert_term( $term, $taxonomy );
+			}
 		}
+
 		if ( is_wp_error($term_info) )
 			return $term_info;
 		$term_ids[] = $term_info['term_id'];
diff --git tests/phpunit/tests/term/wpSetObjectTerms.php tests/phpunit/tests/term/wpSetObjectTerms.php
index 2dde5fd..ba6a329 100644
--- tests/phpunit/tests/term/wpSetObjectTerms.php
+++ tests/phpunit/tests/term/wpSetObjectTerms.php
@@ -318,7 +318,7 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
 		$tt_ids = wp_set_object_terms( self::$post_ids[0], 'foo', 'wptests_tax' );
 
 		$this->assertNotEmpty( $tt_ids );
-		$term = get_term( $tt_ids[0] );
+		$term = get_term_by( 'term_taxonomy_id', $tt_ids[0] );
 		$this->assertInstanceOf( 'WP_Term', $term );
 		$this->assertSame( 'foo', $term->slug );
 	}
@@ -335,7 +335,7 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
 		$tt_ids = wp_set_object_terms( self::$post_ids[0], 'foo', 'wptests_tax' );
 
 		$this->assertNotEmpty( $tt_ids );
-		$term = get_term( $tt_ids[0] );
+		$term = get_term_by( 'term_taxonomy_id', $tt_ids[0] );
 		$this->assertInstanceOf( 'WP_Term', $term );
 		$this->assertSame( $t, $term->term_id );
 	}
@@ -352,7 +352,7 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
 		$tt_ids = wp_set_object_terms( self::$post_ids[0], 'Bar', 'wptests_tax' );
 
 		$this->assertNotEmpty( $tt_ids );
-		$term = get_term( $tt_ids[0] );
+		$term = get_term_by( 'term_taxonomy_id', $tt_ids[0] );
 		$this->assertInstanceOf( 'WP_Term', $term );
 		$this->assertSame( $t, $term->term_id );
 	}
@@ -375,7 +375,7 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
 		$tt_ids = wp_set_object_terms( self::$post_ids[0], 'Bar', 'wptests_tax' );
 
 		$this->assertNotEmpty( $tt_ids );
-		$term = get_term( $tt_ids[0] );
+		$term = get_term_by( 'term_taxonomy_id', $tt_ids[0] );
 		$this->assertInstanceOf( 'WP_Term', $term );
 		$this->assertSame( $t2, $term->term_id );
 	}
@@ -387,4 +387,22 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
 
 		$this->assertSame( array(), $tt_ids );
 	}
+
+	/**
+	 * @ticket 37009
+	 * @group bbg
+	 */
+	public function test_slug_of_newly_created_term_should_be_suffixed_when_matching_slug_of_existing_term() {
+		register_taxonomy( 'wptests_tax', 'post' );
+
+		$t = self::factory()->term->create( array(
+			'taxonomy' => 'wptests_tax',
+			'name' => '$foo',
+			'slug' => 'foo',
+		) );
+
+		$tt_ids = wp_set_object_terms( self::$post_ids[0], array( '$foo', '#foo' ), 'wptests_tax' );
+
+		print_r( $tt_ids );
+	}
 }
