Index: src/wp-includes/class-wp-xmlrpc-server.php
===================================================================
--- src/wp-includes/class-wp-xmlrpc-server.php	(revision 37982)
+++ src/wp-includes/class-wp-xmlrpc-server.php	(working copy)
@@ -399,6 +399,65 @@
 	}
 
 	/**
+	 * Retrieve custom fields for term.
+	 *
+	 * @since 4.6.0
+	 *
+	 * @param int $post_id Post ID.
+	 * @return array Custom fields, if exist.
+	 */
+	public function get_term_custom_fields($term_id) {
+		$term_id = (int) $term_id;
+	
+		$custom_fields = array();
+	
+		foreach ( (array) has_term_meta($term_id) as $meta ) {
+
+			if ( ! current_user_can( 'manage_categories' ) )
+				continue;
+
+			$custom_fields[] = array(
+				"id"    => $meta['meta_id'],
+				"key"   => $meta['meta_key'],
+				"value" => $meta['meta_value']
+			);
+		}
+	
+		return $custom_fields;
+	}
+	
+	/**
+	 * Set custom fields for term.
+	 *
+	 * @since 4.6.0
+	 *
+	 * @param int $post_id Post ID.
+	 * @param array $fields Custom fields.
+	 */
+	public function set_term_custom_fields($term_id, $fields) {
+		$term_id = (int) $term_id;
+
+		foreach ( (array) $fields as $meta ) {
+			if ( isset($meta['id']) ) {
+				$meta['id'] = (int) $meta['id'];
+				$pmeta = get_metadata_by_mid( 'term', $meta['id'] );
+				if ( isset($meta['key']) ) {
+					$meta['key'] = wp_unslash( $meta['key'] );
+					if ( $meta['key'] !== $pmeta->meta_key )
+						continue;
+					$meta['value'] = wp_unslash( $meta['value'] );
+					if ( current_user_can( 'manage_categories' ) )
+						update_metadata_by_mid( 'term', $meta['id'], $meta['value'] );
+				} elseif ( current_user_can( 'manage_categories' ) ) {
+					delete_metadata_by_mid( 'term', $meta['id'] );
+				}
+			} elseif ( current_user_can( 'manage_categories' ) ) {
+				add_term_meta( $term_id, $meta['key'], $meta['value'] );
+			}
+		}
+	}
+
+	/**
 	 * Set up blog options property.
 	 *
 	 * Passes property through {@see 'xmlrpc_blog_options'} filter.
@@ -737,6 +796,9 @@
 		// Count we are happy to return as an integer because people really shouldn't use terms that much.
 		$_term['count'] = intval( $_term['count'] );
 
+		// Get term meta
+		$_term['custom_fields'] = $this->get_term_custom_fields($_term['term_id']);
+
 		/**
 		 * Filters XML-RPC-prepared data for the given term.
 		 *
@@ -1916,6 +1978,10 @@
 		if ( ! $term )
 			return new IXR_Error( 500, __( 'Sorry, your term could not be created. Something wrong happened.' ) );
 
+		if ( isset( $content_struct['custom_fields'] ) ) {
+			$this->set_term_custom_fields( $term['term_id'], $content_struct['custom_fields'] );
+		}
+
 		return strval( $term['term_id'] );
 	}
 
@@ -2014,6 +2080,11 @@
 		if ( ! $term )
 			return new IXR_Error( 500, __( 'Sorry, editing the term failed.' ) );
 
+		// Update term meta
+		if ( isset( $content_struct['custom_fields'] ) ) {
+			$this->set_term_custom_fields( $term_id, $content_struct['custom_fields'] );
+		}
+
 		return true;
 	}
 
Index: src/wp-includes/taxonomy.php
===================================================================
--- src/wp-includes/taxonomy.php	(revision 37982)
+++ src/wp-includes/taxonomy.php	(working copy)
@@ -1370,6 +1370,29 @@
 }
 
 /**
+ * Get meta data for the given term ID.
+ *
+ * @since 4.6.0
+ *
+ * @global wpdb $wpdb WordPress database abstraction object.
+ *
+ * @param int $term_id
+ * @return array|false
+ */
+function has_term_meta( $term_id ) {
+	// Bail if term meta table is not installed.
+	if ( get_option( 'db_version' ) < 34370 ) {
+		return;
+	}
+
+	global $wpdb;
+
+	return $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value, meta_id, term_id
+		FROM $wpdb->termmeta WHERE term_id = %d
+		ORDER BY meta_key,meta_id", $term_id), ARRAY_A );
+}
+
+/**
  * Check if Term exists.
  *
  * Formerly is_term(), introduced in 2.3.0.
Index: tests/phpunit/tests/term/meta.php
===================================================================
--- tests/phpunit/tests/term/meta.php	(revision 37982)
+++ tests/phpunit/tests/term/meta.php	(working copy)
@@ -407,4 +407,18 @@
 	public static function set_cache_results( $q ) {
 		$q->set( 'cache_results', true );
 	}
+	
+	/**
+	 * @ticket 35991
+	 */
+	public function test_has_term_meta() {
+		$t = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax' ) );
+		
+		$term_meta_id = add_term_meta( $t, 'foo', 'bar' );
+		$meta = has_term_meta( $t );
+
+		$this->assertInternalType( 'array', $meta );
+		$this->assertEquals( array( 'meta_key' => 'foo', 'meta_value' => 'bar', 'meta_id' => $term_meta_id, 'term_id' => $t ), $meta[0] );
+	}
+
 }
Index: tests/phpunit/tests/xmlrpc/wp/getTerm.php
===================================================================
--- tests/phpunit/tests/xmlrpc/wp/getTerm.php	(revision 37983)
+++ tests/phpunit/tests/xmlrpc/wp/getTerm.php	(working copy)
@@ -11,6 +11,9 @@
 
 		$this->term = wp_insert_term( 'term' . rand_str() , 'category' );
 		$this->assertInternalType( 'array', $this->term );
+
+		// Add term meta to test wp.getTerm
+		add_term_meta( $this->term['term_id'], 'foo', 'bar' );
 	}
 
 	function test_invalid_username_password() {
@@ -73,6 +76,17 @@
 		$result = $this->myxmlrpcserver->wp_getTerm( array( 1, 'editor', 'editor', 'category', $this->term['term_id'] ) );
 
 		$this->assertNotInstanceOf( 'IXR_Error', $result );
+
+		/**
+		 * Check custom term meta
+		 * 
+		 * @ticket 35991
+		 */
+		$this->assertInternalType( 'array', $result['custom_fields'] );
+		$term_meta = get_term_meta( $this->term['term_id'], '', true );
+		$this->assertEquals( $term_meta['foo'][0], $result['custom_fields'][0]['value'] );
+		unset($result['custom_fields']);
+
 		$this->assertEquals( $result, $term );
 
 		// Check DataTypes
Index: tests/phpunit/tests/xmlrpc/wp/newTerm.php
===================================================================
--- tests/phpunit/tests/xmlrpc/wp/newTerm.php	(revision 37982)
+++ tests/phpunit/tests/xmlrpc/wp/newTerm.php	(working copy)
@@ -107,4 +107,14 @@
 		$this->assertNotInstanceOf( 'IXR_Error', $result );
 		$this->assertStringMatchesFormat( '%d', $result );
 	}
+
+	/**
+	 * @ticket 35991
+	 */
+	public function test_add_term_meta() {
+		$this->make_user_by_role( 'editor' );
+		$result = $this->myxmlrpcserver->wp_newTerm( array( 1, 'editor', 'editor', array( 'taxonomy' => 'category', 'name' => 'Test meta', 'custom_fields' => array( array('key' => 'key1', 'value' => 'value1') ) ) ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+		$this->assertStringMatchesFormat( '%d', $result );
+	}
 }
Index: tests/phpunit/tests/xmlrpc/wp/getTerms.php
===================================================================
--- tests/phpunit/tests/xmlrpc/wp/getTerms.php	(revision 37983)
+++ tests/phpunit/tests/xmlrpc/wp/getTerms.php	(working copy)
@@ -49,6 +49,9 @@
 
 		foreach( $results as $term ) {
 			$this->assertInternalType( 'int', $term['count'] );
+			
+			// Check custom term meta
+			$this->assertInternalType( 'array', $term['custom_fields'] );
 
 			// We expect all other IDs to be strings not integers so we don't return something larger than an XMLRPC integer can describe.
 			$this->assertStringMatchesFormat( '%d', $term['term_id'] );
