diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index 9e9f18e0113717ad6853ea5d4512661a897e926c..c913c82de1acdecbf3328c37fe7529dfbab193ba 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -22,7 +22,6 @@ use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionFactory;
  * @method Product setHasError(bool $value)
  * @method \Magento\Catalog\Model\ResourceModel\Product getResource()
  * @method null|bool getHasError()
- * @method Product setAssociatedProductIds(array $productIds)
  * @method array getAssociatedProductIds()
  * @method Product setNewVariationsAttributeSetId(int $value)
  * @method int getNewVariationsAttributeSetId()
@@ -2614,4 +2613,16 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
         }
         return $this->mediaGalleryProcessor;
     }
+
+    /**
+     * Set the associated products
+     *
+     * @param array $productIds
+     * @return $this
+     */
+    public function setAssociatedProductIds(array $productIds)
+    {
+        $this->getExtensionAttributes()->setConfigurableProductLinks($productIds);
+        return $this;
+    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
index 0fdfbd3bfa172ee597414ed3ab4c46bbac2a9549..5575d6f7ef56fa4f7f2fed433299c01eaa4ba98d 100644
--- a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
+++ b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
@@ -32,6 +32,16 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI
      */
     private $dataObjectHelper;
 
+    /**
+     * @var \Magento\ConfigurableProduct\Helper\Product\Options\Factory;
+     */
+    private $optionsFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory
+     */
+    private $attributeFactory;
+
     /**
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
      * @param \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory
@@ -102,9 +112,28 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI
             throw new StateException(__('Product has been already attached'));
         }
 
+        $configurableProductOptions = $product->getExtensionAttributes()->getConfigurableProductOptions();
+        if (empty($configurableProductOptions)) {
+            throw new StateException(__('Parent product does not have configurable product options'));
+        }
+
+        $attributeIds = [];
+        foreach ($configurableProductOptions as $configurableProductOption) {
+            $attributeCode = $configurableProductOption->getProductAttribute()->getAttributeCode();
+            if (!$child->getData($attributeCode)) {
+                throw new StateException(__('Child product does not have attribute value %1', $attributeCode));
+            }
+            $attributeIds[] = $configurableProductOption->getAttributeId();
+        }
+        $configurableOptionData = $this->getConfigurableAttributesData($attributeIds);
+
+        /** @var \Magento\ConfigurableProduct\Helper\Product\Options\Factory $optionFactory */
+        $optionFactory = $this->getOptionsFactory();
+        $options = $optionFactory->create($configurableOptionData);
         $childrenIds[] = $child->getId();
+        $product->getExtensionAttributes()->setConfigurableProductOptions($options);
         $product->getExtensionAttributes()->setConfigurableProductLinks($childrenIds);
-        $product->save();
+        $this->productRepository->save($product);
         return true;
     }
 
@@ -133,7 +162,75 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI
             throw new NoSuchEntityException(__('Requested option doesn\'t exist'));
         }
         $product->getExtensionAttributes()->setConfigurableProductLinks($ids);
-        $product->save();
+        $this->productRepository->save($product);
         return true;
     }
+
+    /**
+     * Get Options Factory
+     *
+     * @return \Magento\ConfigurableProduct\Helper\Product\Options\Factory
+     *
+     * @deprecated
+     */
+    private function getOptionsFactory()
+    {
+        if (!$this->optionsFactory) {
+            $this->optionsFactory = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\ConfigurableProduct\Helper\Product\Options\Factory::class);
+        }
+        return $this->optionsFactory;
+    }
+
+    /**
+     * Get Attribute Factory
+     *
+     * @return \Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory
+     *
+     * @deprecated
+     */
+    private function getAttributeFactory()
+    {
+        if (!$this->attributeFactory) {
+            $this->attributeFactory = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory::class);
+        }
+        return $this->attributeFactory;
+    }
+
+    /**
+     * Get Configurable Attribute Data
+     *
+     * @param int[] $attributeIds
+     * @return array
+     */
+    private function getConfigurableAttributesData($attributeIds)
+    {
+        $configurableAttributesData = [];
+        $attributeValues = [];
+        $attributes = $this->getAttributeFactory()->create()
+            ->getCollection()
+            ->addFieldToFilter('attribute_id', $attributeIds)
+            ->getItems();
+        foreach ($attributes as $attribute) {
+            foreach ($attribute->getOptions() as $option) {
+                if ($option->getValue()) {
+                    $attributeValues[] = [
+                        'label' => $option->getLabel(),
+                        'attribute_id' => $attribute->getId(),
+                        'value_index' => $option->getValue(),
+                    ];
+                }
+            }
+            $configurableAttributesData[] =
+                [
+                    'attribute_id' => $attribute->getId(),
+                    'code' => $attribute->getAttributeCode(),
+                    'label' => $attribute->getStoreLabel(),
+                    'values' => $attributeValues,
+                ];
+        }
+
+        return $configurableAttributesData;
+    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
index 6b69888e6dd0924cf6e090bdb1eb0af2daddaab1..5a7886ea3ea640c2f276ffb7eedeaa243ff9e790 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
@@ -6,8 +6,8 @@
 
 namespace Magento\ConfigurableProduct\Test\Unit\Model;
 
+use Magento\ConfigurableProduct\Model\LinkManagement;
 use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
-use Magento\ConfigurableProduct\Test\Unit\Model\Product\ProductExtensionAttributes;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -146,15 +146,59 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
 
         $configurable = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
             ->disableOriginalConstructor()
+            ->setMethods(['getId', 'getExtensionAttributes'])
+            ->getMock();
+        $simple = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getId', 'getData'])
             ->getMock();
 
-        $configurable->expects($this->any())->method('getId')->will($this->returnValue(666));
+        $extensionAttributesMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductExtension::class)
+            ->disableOriginalConstructor()
+            ->setMethods([
+                'getConfigurableProductOptions', 'setConfigurableProductOptions', 'setConfigurableProductLinks'
+            ])
+            ->getMock();
+        $optionMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Api\Data\Option::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getProductAttribute', 'getAttributeId'])
+            ->getMock();
+        $productAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttributeCode'])
+            ->getMock();
+        $optionsFactoryMock = $this->getMockBuilder(\Magento\ConfigurableProduct\Helper\Product\Options\Factory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $reflectionClass = new \ReflectionClass(\Magento\ConfigurableProduct\Model\LinkManagement::class);
+        $optionsFactoryReflectionProperty = $reflectionClass->getProperty('optionsFactory');
+        $optionsFactoryReflectionProperty->setAccessible(true);
+        $optionsFactoryReflectionProperty->setValue($this->object, $optionsFactoryMock);
 
-        $simple = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+        $attributeFactoryMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory::class)
             ->disableOriginalConstructor()
+            ->setMethods(['create'])
             ->getMock();
+        $attributeFactoryReflectionProperty = $reflectionClass->getProperty('attributeFactory');
+        $attributeFactoryReflectionProperty->setAccessible(true);
+        $attributeFactoryReflectionProperty->setValue($this->object, $attributeFactoryMock);
 
-        $simple->expects($this->any())->method('getId')->will($this->returnValue(999));
+        $attributeMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getCollection', 'getOptions', 'getId', 'getAttributeCode', 'getStoreLabel'])
+            ->getMock();
+        $attributeOptionMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Option::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getValue', 'getLabel'])
+            ->getMock();
+
+        $attributeCollectionMock = $this->getMockBuilder(
+            \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection::class
+        )
+            ->disableOriginalConstructor()
+            ->setMethods(['addFieldToFilter', 'getItems'])
+            ->getMock();
 
         $this->productRepository->expects($this->at(0))->method('get')->with($productSku)->willReturn($configurable);
         $this->productRepository->expects($this->at(1))->method('get')->with($childSku)->willReturn($simple);
@@ -164,15 +208,30 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
                 $this->returnValue([0 => [1, 2, 3]])
             );
 
-        $extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class)
-            ->setMethods(['setConfigurableProductLinks'])
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
+        $configurable->expects($this->any())->method('getId')->will($this->returnValue(666));
+        $simple->expects($this->any())->method('getId')->will($this->returnValue(999));
+
+        $configurable->expects($this->any())->method('getExtensionAttributes')->willReturn($extensionAttributesMock);
+        $extensionAttributesMock->expects($this->any())
+            ->method('getConfigurableProductOptions')
+            ->willReturn([$optionMock]);
+        $optionMock->expects($this->any())->method('getProductAttribute')->willReturn($productAttributeMock);
+        $productAttributeMock->expects($this->any())->method('getAttributeCode')->willReturn('color');
+        $simple->expects($this->any())->method('getData')->willReturn('color');
+        $optionMock->expects($this->any())->method('getAttributeId')->willReturn('1');
 
-        $configurable->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes);
-        $extensionAttributes->expects($this->once())->method('setConfigurableProductLinks')->willReturnSelf();
+        $optionsFactoryMock->expects($this->any())->method('create')->willReturn([$optionMock]);
+        $attributeFactoryMock->expects($this->any())->method('create')->willReturn($attributeMock);
+        $attributeMock->expects($this->any())->method('getCollection')->willReturn($attributeCollectionMock);
+        $attributeCollectionMock->expects($this->any())->method('addFieldToFilter')->willReturnSelf();
+        $attributeCollectionMock->expects($this->any())->method('getItems')->willReturn([$attributeMock]);
 
-        $configurable->expects($this->once())->method('save');
+        $attributeMock->expects($this->any())->method('getOptions')->willReturn([$attributeOptionMock]);
+
+        $extensionAttributesMock->expects($this->any())->method('setConfigurableProductOptions');
+        $extensionAttributesMock->expects($this->any())->method('setConfigurableProductLinks');
+
+        $this->productRepository->expects($this->once())->method('save');
 
         $this->assertTrue(true, $this->object->addChild($productSku, $childSku));
     }
@@ -243,15 +302,13 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
         $productType->expects($this->once())->method('getUsedProducts')
             ->will($this->returnValue([$option]));
 
-        $extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class)
+        $extensionAttributesMock = $this->getMockBuilder(\Magento\Framework\Api\ExtensionAttributesInterface::class)
             ->setMethods(['setConfigurableProductLinks'])
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
 
-        $product->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes);
-        $extensionAttributes->expects($this->once())->method('setConfigurableProductLinks')->willReturnSelf();
-
-        $product->expects($this->once())->method('save');
+        $product->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributesMock);
+        $this->productRepository->expects($this->once())->method('save');
         $this->assertTrue($this->object->removeChild($productSku, $childSku));
     }
 
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
index e4129a0739912c05dbb8546beab7f028945ad5f6..1a06be978d34c897f10aadd32e7f3e1720b1983b 100644
--- a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
@@ -6,12 +6,33 @@
  */
 namespace Magento\ConfigurableProduct\Api;
 
+use Magento\Eav\Model\AttributeRepository;
+
 class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
 {
     const SERVICE_NAME = 'configurableProductLinkManagementV1';
     const SERVICE_VERSION = 'V1';
     const RESOURCE_PATH = '/V1/configurable-products';
 
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * @var AttributeRepository
+     */
+    protected $attributeRepository;
+
+    /**
+     * Execute per test initialization
+     */
+    public function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->attributeRepository = $this->objectManager->get(\Magento\Eav\Model\AttributeRepository::class);
+    }
+
     /**
      * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
      */
@@ -40,14 +61,76 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
     }
 
     /**
-     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_simple_77.php
      * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_simple_77.php
      * @magentoApiDataFixture Magento/ConfigurableProduct/_files/delete_association.php
      */
     public function testAddChild()
     {
         $productSku = 'configurable';
         $childSku = 'simple_77';
+        $res = $this->addChild($productSku, $childSku);
+        $this->assertTrue($res);
+    }
+
+    /**
+     * Test the full flow of creating a configurable product and adding a child via REST
+     *
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
+     */
+    public function testAddChildFullRestCreation()
+    {
+        $productSku = 'configurable-product-sku';
+        $childSku = 'simple-product-sku';
+
+        $this->createConfigurableProduct($productSku);
+        $attribute = $this->attributeRepository->get('catalog_product', 'test_configurable');
+        $attributeValue = $attribute->getOptions()[1]->getValue();
+        $this->addOptionToConfigurableProduct($productSku, $attribute->getAttributeId(), $attributeValue);
+        $this->createSimpleProduct($childSku, $attributeValue);
+        $res = $this->addChild($productSku, $childSku);
+        $this->assertTrue($res);
+
+        // confirm that the simple product was added
+        $children = $this->getChildren($productSku);
+        $added = false;
+        foreach ($children as $child) {
+            if ($child['sku'] == $childSku) {
+                $added = true;
+                break;
+            }
+        }
+        $this->assertTrue($added);
+
+        // clean up products
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => 'catalogProductRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogProductRepositoryV1DeleteById',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, ['sku' => $productSku]);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $childSku,
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => 'catalogProductRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogProductRepositoryV1DeleteById',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, ['sku' => $childSku]);
+    }
+
+    private function addChild($productSku, $childSku)
+    {
         $serviceInfo = [
             'rest' => [
                 'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/child',
@@ -59,8 +142,90 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
                 'operation' => self::SERVICE_NAME . 'AddChild'
             ]
         ];
-        $res = $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'childSku' => $childSku]);
-        $this->assertTrue($res);
+        return $this->_webApiCall($serviceInfo, ['sku' => $productSku, 'childSku' => $childSku]);
+    }
+
+    protected function createConfigurableProduct($productSku)
+    {
+        $requestData = [
+            'product' => [
+                'sku' => $productSku,
+                'name' => 'configurable-product-' . $productSku,
+                'type_id' => 'configurable',
+                'price' => 50,
+                'attribute_set_id' => 4
+            ]
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products',
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST
+            ],
+            'soap' => [
+                'service' => 'catalogProductRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogProductRepositoryV1Save',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    protected function addOptionToConfigurableProduct($productSku, $attributeId, $attributeValue)
+    {
+        $requestData = [
+            'sku' => $productSku,
+            'option' => [
+                'attribute_id' => $attributeId,
+                'label' => 'test_configurable',
+                'position' => 0,
+                'is_use_default' => true,
+                'values' => [
+                    ['value_index' => $attributeValue],
+                ]
+            ]
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/configurable-products/'. $productSku .'/options',
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'configurableProductOptionRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'configurableProductOptionRepositoryV1Save',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    protected function createSimpleProduct($sku, $attributeValue)
+    {
+        $requestData = [
+            'product' => [
+                'sku' => $sku,
+                'name' => 'simple-product-' . $sku,
+                'type_id' => 'simple',
+                'attribute_set_id' => 4,
+                'price' => 3.62,
+                'status' => 1,
+                'visibility' => 4,
+                'custom_attributes' => [
+                    ['attribute_code' => 'test_configurable', 'value' => $attributeValue],
+                ]
+            ]
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products',
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'catalogProductRepositoryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogProductRepositoryV1Save',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, $requestData);
     }
 
     /**
@@ -93,7 +258,7 @@ class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
 
     /**
      * @param string $productSku
-     * @return string
+     * @return string[]
      */
     protected function getChildren($productSku)
     {
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
index ff08056e4b18def3f520d2a5d9f2090b168d5ec8..0d8361b4751e38a96ae4dbb7aadb86510dad92dc 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Creates a simple product to be used for test cases.
+ *
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -72,7 +74,8 @@ $product->setTypeId(Type::TYPE_SIMPLE)
             'is_in_stock'               => 1,
         ]
     )->setCanSaveCustomOptions(true)
-    ->setHasOptions(true);
+    ->setHasOptions(true)
+    ->setCustomAttribute('test_configurable', 42);
 
 $oldOptions = [
     [