diff --git a/src/Aggregation/Bucketing/CompositeAggregation.php b/src/Aggregation/Bucketing/CompositeAggregation.php
new file mode 100644
index 0000000000000000000000000000000000000000..d36c9007b805d9ef70bc4d67962258a3dad266c5
--- /dev/null
+++ b/src/Aggregation/Bucketing/CompositeAggregation.php
@@ -0,0 +1,80 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchDSL\Aggregation\Bucketing;
+
+use ONGR\ElasticsearchDSL\Aggregation\AbstractAggregation;
+use ONGR\ElasticsearchDSL\Aggregation\Type\BucketingTrait;
+use ONGR\ElasticsearchDSL\BuilderInterface;
+
+/**
+ * Class representing composite aggregation.
+ *
+ * @link https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-composite-aggregation.html
+ */
+class CompositeAggregation extends AbstractAggregation
+{
+    use BucketingTrait;
+
+    /**
+     * @var BuilderInterface[]
+     */
+    private $sources = [];
+
+    /**
+     * Inner aggregations container init.
+     *
+     * @param string             $name
+     * @param BuilderInterface[] $sources
+     */
+    public function __construct($name, $sources = [])
+    {
+        parent::__construct($name);
+
+        foreach ($sources as $agg) {
+            $this->addSource($agg);
+        }
+    }
+
+    /**
+     * @param BuilderInterface $agg
+     *
+     * @throws \LogicException
+     *
+     * @return self
+     */
+    public function addSource(BuilderInterface $agg)
+    {
+        $this->sources[] = [
+            $agg->getName() => [ $agg->getType() => $agg->getArray() ]
+        ];
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getArray()
+    {
+        return [
+            'sources' => $this->sources,
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return 'composite';
+    }
+}
diff --git a/tests/Unit/Aggregation/Bucketing/CompositeAggregationTest.php b/tests/Unit/Aggregation/Bucketing/CompositeAggregationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d10953206ec4b4070f4b4e60450eec1d6e89e72d
--- /dev/null
+++ b/tests/Unit/Aggregation/Bucketing/CompositeAggregationTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the ONGR package.
+ *
+ * (c) NFQ Technologies UAB <info@nfq.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ONGR\ElasticsearchDSL\Tests\Unit\Bucketing\Aggregation;
+
+use ONGR\ElasticsearchDSL\Aggregation\Bucketing\CompositeAggregation;
+use ONGR\ElasticsearchDSL\Aggregation\Bucketing\TermsAggregation;
+
+class CompositeAggregationTest extends \PHPUnit\Framework\TestCase
+{
+    /**
+     * Test for composite aggregation toArray() method exception.
+     */
+    public function testToArray()
+    {
+        $compositeAgg = new CompositeAggregation('composite_test_agg');
+        $termsAgg = new TermsAggregation('test_term_agg', 'test_field');
+        $compositeAgg->addSource($termsAgg);
+
+        $expectedResult = [
+            'composite' => [
+                'sources' =>  [
+                    [
+                        'test_term_agg' => [ 'terms' => ['field' => 'test_field'] ],
+                    ]
+                ]
+            ],
+        ];
+
+        $this->assertEquals($expectedResult, $compositeAgg->toArray());
+    }
+
+    /**
+     * Tests getType method.
+     */
+    public function testGetType()
+    {
+        $aggregation = new CompositeAggregation('foo');
+        $result = $aggregation->getType();
+        $this->assertEquals('composite', $result);
+    }
+}