diff --git a/core/includes/common.inc b/core/includes/common.inc
index c8f06b0..58d6d11 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -7699,39 +7699,6 @@ function drupal_check_incompatibility($v, $current_version) {
 }
 
 /**
- * Performs one or more XML-RPC request(s).
- *
- * Usage example:
- * @code
- * $result = xmlrpc('http://example.com/xmlrpc.php', array(
- *   'service.methodName' => array($parameter, $second, $third),
- * ));
- * @endcode
- *
- * @param $url
- *   An absolute URL of the XML-RPC endpoint.
- * @param $args
- *   An associative array whose keys are the methods to call and whose values
- *   are the arguments to pass to the respective method. If multiple methods
- *   are specified, a system.multicall is performed.
- * @param $options
- *   (optional) An array of options to pass along to drupal_http_request().
- *
- * @return
- *   For one request:
- *     Either the return value of the method on success, or FALSE.
- *     If FALSE is returned, see xmlrpc_errno() and xmlrpc_error_msg().
- *   For multiple requests:
- *     An array of results. Each result will either be the result
- *     returned by the method called, or an xmlrpc_error object if the call
- *     failed. See xmlrpc_error().
- */
-function xmlrpc($url, $args, $options = array()) {
-  require_once DRUPAL_ROOT . '/core/includes/xmlrpc.inc';
-  return _xmlrpc($url, $args, $options);
-}
-
-/**
  * Retrieves a list of all available archivers.
  *
  * @see hook_archiver_info()
diff --git a/core/modules/simpletest/simpletest.info b/core/modules/simpletest/simpletest.info
index cf55121..6b481fe 100644
--- a/core/modules/simpletest/simpletest.info
+++ b/core/modules/simpletest/simpletest.info
@@ -39,7 +39,6 @@ files[] = tests/theme.test
 files[] = tests/unicode.test
 files[] = tests/update.test
 files[] = tests/uuid.test
-files[] = tests/xmlrpc.test
 files[] = tests/upgrade/upgrade.test
 files[] = tests/upgrade/upgrade_bare.test
 files[] = tests/upgrade/upgrade_filled.test
diff --git a/core/modules/simpletest/tests/xmlrpc.test b/core/modules/xmlrpc/tests/xmlrpc.test
similarity index 81%
rename from core/modules/simpletest/tests/xmlrpc.test
rename to core/modules/xmlrpc/tests/xmlrpc.test
index 60b9624..a51f49b 100644
--- a/core/modules/simpletest/tests/xmlrpc.test
+++ b/core/modules/xmlrpc/tests/xmlrpc.test
@@ -13,6 +13,10 @@ class XMLRPCBasicTestCase extends DrupalWebTestCase {
     );
   }
 
+  function setUp() {
+    parent::setUp('xmlrpc');
+  }
+
   /**
    * Ensure that a basic XML-RPC call with no parameters works.
    */
@@ -27,9 +31,8 @@ class XMLRPCBasicTestCase extends DrupalWebTestCase {
     );
 
     // Invoke XML-RPC call to get list of methods.
-    $url = url(NULL, array('absolute' => TRUE)) . 'core/xmlrpc.php';
-    $methods = xmlrpc($url, array('system.listMethods' => array()));
-
+    $url = url(NULL, array('absolute' => TRUE)) . 'xmlrpc.php';
+    $methods = xmlrpc_request($url, array('system.listMethods' => array()));
     // Ensure that the minimum methods were found.
     $count = 0;
     foreach ($methods as $method) {
@@ -45,8 +48,8 @@ class XMLRPCBasicTestCase extends DrupalWebTestCase {
    * Ensure that system.methodSignature returns an array of signatures.
    */
   protected function testMethodSignature() {
-    $url = url(NULL, array('absolute' => TRUE)) . 'core/xmlrpc.php';
-    $signature = xmlrpc($url, array('system.methodSignature' => array('system.listMethods')));
+    $url = url(NULL, array('absolute' => TRUE)) . 'xmlrpc.php';
+    $signature = xmlrpc_request($url, array('system.methodSignature' => array('system.listMethods')));
     $this->assert(is_array($signature) && !empty($signature) && is_array($signature[0]),
       t('system.methodSignature returns an array of signature arrays.'));
   }
@@ -90,14 +93,14 @@ class XMLRPCValidator1IncTestCase extends DrupalWebTestCase {
   }
 
   function setUp() {
-    parent::setUp('xmlrpc_test');
+    parent::setUp('xmlrpc', 'xmlrpc_test');
   }
 
   /**
    * Run validator1 tests.
    */
   function testValidator1() {
-    $xml_url = url(NULL, array('absolute' => TRUE)) . 'core/xmlrpc.php';
+    $xml_url = url(NULL, array('absolute' => TRUE)) . 'xmlrpc.php';
     srand();
     mt_srand();
 
@@ -110,17 +113,17 @@ class XMLRPCValidator1IncTestCase extends DrupalWebTestCase {
                   array('larry' => mt_rand(-100, 100)));
     shuffle($array_1);
     $l_res_1 = xmlrpc_test_arrayOfStructsTest($array_1);
-    $r_res_1 = xmlrpc($xml_url, array('validator1.arrayOfStructsTest' => array($array_1)));
+    $r_res_1 = xmlrpc_request($xml_url, array('validator1.arrayOfStructsTest' => array($array_1)));
     $this->assertIdentical($l_res_1, $r_res_1);
 
     $string_2 = 't\'&>>zf"md>yr>xlcev<h<"k&j<og"w&&>">>uai"np&s>>q\'&b<>"&&&';
     $l_res_2 = xmlrpc_test_countTheEntities($string_2);
-    $r_res_2 = xmlrpc($xml_url, array('validator1.countTheEntities' => array($string_2)));
+    $r_res_2 = xmlrpc_request($xml_url, array('validator1.countTheEntities' => array($string_2)));
     $this->assertIdentical($l_res_2, $r_res_2);
 
     $struct_3 = array('moe' => mt_rand(-100, 100), 'larry' => mt_rand(-100, 100), 'curly' => mt_rand(-100, 100), 'homer' => mt_rand(-100, 100));
     $l_res_3 = xmlrpc_test_easyStructTest($struct_3);
-    $r_res_3 = xmlrpc($xml_url, array('validator1.easyStructTest' => array($struct_3)));
+    $r_res_3 = xmlrpc_request($xml_url, array('validator1.easyStructTest' => array($struct_3)));
     $this->assertIdentical($l_res_3, $r_res_3);
 
     $struct_4 = array('sub1' => array('bar' => 13),
@@ -128,7 +131,7 @@ class XMLRPCValidator1IncTestCase extends DrupalWebTestCase {
                     'sub3' => array('foo' => 1, 'baz' => 2),
                     'sub4' => array('ss' => array('sss' => array('ssss' => 'sssss'))));
     $l_res_4 = xmlrpc_test_echoStructTest($struct_4);
-    $r_res_4 = xmlrpc($xml_url, array('validator1.echoStructTest' => array($struct_4)));
+    $r_res_4 = xmlrpc_request($xml_url, array('validator1.echoStructTest' => array($struct_4)));
     $this->assertIdentical($l_res_4, $r_res_4);
 
     $int_5     = mt_rand(-100, 100);
@@ -140,7 +143,7 @@ class XMLRPCValidator1IncTestCase extends DrupalWebTestCase {
     $l_res_5 = xmlrpc_test_manyTypesTest($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), $base64_5);
     // See http://drupal.org/node/37766 why this currently fails
     $l_res_5[5] = $l_res_5[5]->data;
-    $r_res_5 = xmlrpc($xml_url, array('validator1.manyTypesTest' => array($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5))));
+    $r_res_5 = xmlrpc_request($xml_url, array('validator1.manyTypesTest' => array($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5))));
     // @todo Contains objects, objects are not equal.
     $this->assertEqual($l_res_5, $r_res_5);
 
@@ -151,7 +154,7 @@ class XMLRPCValidator1IncTestCase extends DrupalWebTestCase {
     }
 
     $l_res_6 = xmlrpc_test_moderateSizeArrayCheck($array_6);
-    $r_res_6 = xmlrpc($xml_url, array('validator1.moderateSizeArrayCheck' => array($array_6)));
+    $r_res_6 = xmlrpc_request($xml_url, array('validator1.moderateSizeArrayCheck' => array($array_6)));
     $this->assertIdentical($l_res_6, $r_res_6);
 
     $struct_7 = array();
@@ -168,13 +171,13 @@ class XMLRPCValidator1IncTestCase extends DrupalWebTestCase {
       }
     }
     $l_res_7 = xmlrpc_test_nestedStructTest($struct_7);
-    $r_res_7 = xmlrpc($xml_url, array('validator1.nestedStructTest' => array($struct_7)));
+    $r_res_7 = xmlrpc_request($xml_url, array('validator1.nestedStructTest' => array($struct_7)));
     $this->assertIdentical($l_res_7, $r_res_7);
 
 
     $int_8 = mt_rand(-100, 100);
     $l_res_8 = xmlrpc_test_simpleStructReturnTest($int_8);
-    $r_res_8 = xmlrpc($xml_url, array('validator1.simpleStructReturnTest' => array($int_8)));
+    $r_res_8 = xmlrpc_request($xml_url, array('validator1.simpleStructReturnTest' => array($int_8)));
     $this->assertIdentical($l_res_8, $r_res_8);
 
     /* Now test multicall */
@@ -189,7 +192,7 @@ class XMLRPCValidator1IncTestCase extends DrupalWebTestCase {
     $x['validator1.simpleStructReturnTest'] = array($int_8);
 
     $a_l_res = array($l_res_1, $l_res_2, $l_res_3, $l_res_4, $l_res_5, $l_res_6, $l_res_7, $l_res_8);
-    $a_r_res = xmlrpc($xml_url, $x);
+    $a_r_res = xmlrpc_request($xml_url, $x);
     $this->assertEqual($a_l_res, $a_r_res);
   }
 }
@@ -204,18 +207,18 @@ class XMLRPCMessagesTestCase extends DrupalWebTestCase {
   }
 
   function setUp() {
-    parent::setUp('xmlrpc_test');
+    parent::setUp('xmlrpc', 'xmlrpc_test');
   }
 
   /**
    * Make sure that XML-RPC can transfer large messages.
    */
   function testSizedMessages() {
-    $xml_url = url(NULL, array('absolute' => TRUE)) . 'core/xmlrpc.php';
+    $xml_url = url(NULL, array('absolute' => TRUE)) . 'xmlrpc.php';
     $sizes = array(8, 80, 160);
     foreach ($sizes as $size) {
       $xml_message_l = xmlrpc_test_message_sized_in_kb($size);
-      $xml_message_r = xmlrpc($xml_url, array('messages.messageSizedInKB' => array($size)));
+      $xml_message_r = xmlrpc_request($xml_url, array('messages.messageSizedInKB' => array($size)));
 
       $this->assertEqual($xml_message_l, $xml_message_r, t('XML-RPC messages.messageSizedInKB of %s Kb size received', array('%s' => $size)));
     }
@@ -228,12 +231,12 @@ class XMLRPCMessagesTestCase extends DrupalWebTestCase {
 
     // Ensure xmlrpc_test_xmlrpc_alter() is disabled and retrieve regular list of methods.
     variable_set('xmlrpc_test_xmlrpc_alter', FALSE);
-    $url = url(NULL, array('absolute' => TRUE)) . 'core/xmlrpc.php';
-    $methods1 = xmlrpc($url, array('system.listMethods' => array()));
+    $url = url(NULL, array('absolute' => TRUE)) . 'xmlrpc.php';
+    $methods1 = xmlrpc_request($url, array('system.listMethods' => array()));
 
     // Enable the alter hook and retrieve the list of methods again.
     variable_set('xmlrpc_test_xmlrpc_alter', TRUE);
-    $methods2 = xmlrpc($url, array('system.listMethods' => array()));
+    $methods2 = xmlrpc_request($url, array('system.listMethods' => array()));
 
     $diff = array_diff($methods1, $methods2);
     $this->assertTrue(is_array($diff) && !empty($diff), t('Method list is altered by hook_xmlrpc_alter'));
diff --git a/core/modules/simpletest/tests/xmlrpc_test.info b/core/modules/xmlrpc/tests/xmlrpc_test.info
similarity index 100%
rename from core/modules/simpletest/tests/xmlrpc_test.info
rename to core/modules/xmlrpc/tests/xmlrpc_test.info
diff --git a/core/modules/simpletest/tests/xmlrpc_test.module b/core/modules/xmlrpc/tests/xmlrpc_test.module
similarity index 100%
rename from core/modules/simpletest/tests/xmlrpc_test.module
rename to core/modules/xmlrpc/tests/xmlrpc_test.module
diff --git a/core/includes/xmlrpc.inc b/core/modules/xmlrpc/xmlrpc.inc
similarity index 100%
rename from core/includes/xmlrpc.inc
rename to core/modules/xmlrpc/xmlrpc.inc
diff --git a/core/modules/xmlrpc/xmlrpc.info b/core/modules/xmlrpc/xmlrpc.info
new file mode 100644
index 0000000..9b764f3
--- /dev/null
+++ b/core/modules/xmlrpc/xmlrpc.info
@@ -0,0 +1,6 @@
+name = XML-RPC
+description = Provides XML-RPC functionality.
+package = Core
+version = VERSION
+files[] = tests/xmlrpc.test
+core = 8.x
diff --git a/core/modules/xmlrpc/xmlrpc.module b/core/modules/xmlrpc/xmlrpc.module
new file mode 100644
index 0000000..2a6ae41
--- /dev/null
+++ b/core/modules/xmlrpc/xmlrpc.module
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Enables XML-RPC functionality.
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function xmlrpc_menu() {
+  $items['xmlrpc.php'] = array(
+    'title' => 'XML-RPC',
+    'page callback' => 'xmlrpc_server_page',
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+    'file' => 'xmlrpc.server.inc',
+  );
+  return $items;
+}
+
+/**
+ * Performs one or more XML-RPC request(s).
+ *
+ * Usage example:
+ * @code
+ * $result = xmlrpc_request('http://example.com/xmlrpc.php', array(
+ *   'service.methodName' => array($parameter, $second, $third),
+ * ));
+ * @endcode
+ *
+ * @param $url
+ *   An absolute URL of the XML-RPC endpoint.
+ * @param $args
+ *   An associative array whose keys are the methods to call and whose values
+ *   are the arguments to pass to the respective method. If multiple methods
+ *   are specified, a system.multicall is performed.
+ * @param $options
+ *   (optional) An array of options to pass along to drupal_http_request().
+ *
+ * @return
+ *   For one request:
+ *     Either the return value of the method on success, or FALSE.
+ *     If FALSE is returned, see xmlrpc_errno() and xmlrpc_error_msg().
+ *   For multiple requests:
+ *     An array of results. Each result will either be the result
+ *     returned by the method called, or an xmlrpc_error object if the call
+ *     failed. See xmlrpc_error().
+ */
+function xmlrpc_request($url, $args, $options = array()) {
+  module_load_include('inc', 'xmlrpc');
+  return _xmlrpc($url, $args, $options);
+}
diff --git a/core/includes/xmlrpcs.inc b/core/modules/xmlrpc/xmlrpc.server.inc
similarity index 98%
rename from core/includes/xmlrpcs.inc
rename to core/modules/xmlrpc/xmlrpc.server.inc
index 118f652..e1c160b 100644
--- a/core/includes/xmlrpcs.inc
+++ b/core/modules/xmlrpc/xmlrpc.server.inc
@@ -2,10 +2,18 @@
 
 /**
  * @file
- * Provides API for defining and handling XML-RPC requests.
+ * Page callback file for the xmlrpc module.
  */
 
 /**
+ * Process an XML-RPC request.
+ */
+function xmlrpc_server_page() {
+  module_load_include('inc', 'xmlrpc');
+  xmlrpc_server(module_invoke_all('xmlrpc'));
+}
+
+/**
  * Invokes XML-RPC methods on this server.
  *
  * @param array $callbacks
diff --git a/core/xmlrpc.php b/core/xmlrpc.php
deleted file mode 100644
index 562aa81..0000000
--- a/core/xmlrpc.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-/**
- * @file
- * PHP page for handling incoming XML-RPC requests from clients.
- */
-
-// Change the directory to the Drupal root.
-chdir('..');
-
-/**
- * Root directory of Drupal installation.
- */
-define('DRUPAL_ROOT', getcwd());
-
-include_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
-drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-include_once DRUPAL_ROOT . '/core/includes/xmlrpc.inc';
-include_once DRUPAL_ROOT . '/core/includes/xmlrpcs.inc';
-
-xmlrpc_server(module_invoke_all('xmlrpc'));
