diff --git a/rest/index.php b/rest/index.php
index fd1d4ddbced0bca102ecf34ad492960cad12fce7..d22809aa39d631484a62b068f3b00ad2a686661c 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -445,6 +445,7 @@ $app->get('/tags/{id}', \Tag\controllers\TagController::class . ':getById');
 $app->put('/tags/{id}', \Tag\controllers\TagController::class . ':update');
 $app->put('/mergeTags', \Tag\controllers\TagController::class . ':merge');
 $app->delete('/tags/{id}', \Tag\controllers\TagController::class . ':delete');
+$app->put('/tags/{id}/link', \Tag\controllers\TagController::class . ':link');
 
 //Templates
 $app->get('/templates', \Template\controllers\TemplateController::class . ':get');
diff --git a/src/app/tag/controllers/TagController.php b/src/app/tag/controllers/TagController.php
index 59b3271d21694717640b088d5399a3ef33ef3604..2062f36a06cb667b10fa16b4a5c4f7162b3b7e23 100644
--- a/src/app/tag/controllers/TagController.php
+++ b/src/app/tag/controllers/TagController.php
@@ -271,4 +271,64 @@ class TagController
 
         return $response->withStatus(204);
     }
+
+    public static function link(Request $request, Response $response, array $args)
+    {
+        if (!Validator::intVal()->validate($args['id'])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Route id is not an integer']);
+        }
+
+        $body = $request->getParsedBody();
+
+        if (!Validator::arrayType()->notEmpty()->validate($body['links'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body links is empty or not an array']);
+        } elseif (in_array($args['id'], $body['links'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body links contains tag']);
+        }
+
+        $tag = TagModel::getById(['id' => $args['id']]);
+        $linkedTags = json_decode($tag['links'], true);
+        $linkedTags = array_merge($linkedTags, $body['links']);
+        $linkedTags = array_unique($linkedTags);
+        foreach ($linkedTags as $key => $linkedTag) {
+            $linkedTags[$key] = (string)$linkedTag;
+        }
+
+        TagModel::update([
+            'set'       => ['links' => json_encode($linkedTags)],
+            'where'     => ['id = ?'],
+            'data'      => [$args['id']]
+        ]);
+        TagModel::update([
+            'postSet'   => ['links' => "jsonb_insert(links, '{0}', '\"{$args['id']}\"')"],
+            'where'     => ['id in (?)', "(links @> ?) = false"],
+            'data'      => [$body['links'], "\"{$args['id']}\""]
+        ]);
+
+        $linkedTagsInfo = TagModel::get([
+            'select' => ['label', 'id'],
+            'where'  => ['id in (?)'],
+            'data'   => [$body['links']]
+        ]);
+        $linkedTagsInfo = array_column($linkedTagsInfo, 'label', 'id');
+
+        foreach ($body['linkedResources'] as $value) {
+            HistoryController::add([
+                'tableName' => 'tags',
+                'recordId'  => $args['resId'],
+                'eventType' => 'UP',
+                'info'      => _LINK_ADDED . " : {$linkedTagsInfo[$value]}",
+                'eventId'   => 'tagModification'
+            ]);
+            HistoryController::add([
+                'tableName' => 'tags',
+                'recordId'  => $value,
+                'eventType' => 'UP',
+                'info'      => _LINK_ADDED . " : {$tag['label']}",
+                'eventId'   => 'tagModification'
+            ]);
+        }
+
+        return $response->withStatus(204);
+    }
 }