diff --git a/capsule-prototype/css/mosaic.css b/capsule-prototype/css/mosaic.css
index 02f0b81c9f65033da7cd8ad3165e683bb8b46ff2..4a8a8ccd8f78604ca9177cc0c78559976b3b0992 100644
--- a/capsule-prototype/css/mosaic.css
+++ b/capsule-prototype/css/mosaic.css
@@ -27,7 +27,7 @@
 	flex-wrap: wrap;
 }
 
-.mosaic_filter_item {
+.mosaic_filter_item, .mosaic_label_filter {
 	width: var(--filter-width);
 	height: var(--filter-height);
 	margin: var(--base-spacing);
@@ -40,6 +40,10 @@
 	align-items: center;
 }
 
+.mosaic_label_filter_enabled {
+  background-color: rgba(255, 255, 255, .5);
+}
+
 .mosaic_category {
 	padding: var(--base-spacing);
 	margin: var(--base-spacing);
diff --git a/capsule-prototype/css/popup.css b/capsule-prototype/css/popup.css
index b8baa3e33acc276e6cfe75feb0fc1746987a091e..b8f80ff6251cbf3a4a017b4bcca1abf41aa5f3ce 100644
--- a/capsule-prototype/css/popup.css
+++ b/capsule-prototype/css/popup.css
@@ -1,4 +1,27 @@
 
+#popupLabelsInput {
+  padding: 0;
+}
+
+#popupLabelsInput label {
+  cursor: pointer;
+  width: fit-content;
+  padding: 1px;
+  margin: 1px;
+}
+
+#popupLabelsInput input:checked + label {
+  background-color: rgba(255, 255, 255, .5);
+}
+
+#new_annotation_label {
+  color: white;
+  background-color: rgba(0, 0, 0, .5);
+  border: 0;
+  margin: 0;
+  margin-bottom: 2px;
+  font-size: 100%;
+}
 
 #popupSpace, #popupAlertSpace, #popupAddLinkSpace, #popupSettingsSpace {
 	width: 100%;
diff --git a/capsule-prototype/index.html b/capsule-prototype/index.html
index fbe9317f4b4c7947720fa010b85c513144165f6c..5f56bad57f2d74dea3569fdb98a54d8afa861639 100644
--- a/capsule-prototype/index.html
+++ b/capsule-prototype/index.html
@@ -184,6 +184,14 @@
 
 					<div class="popupRightItem" id="popupSpeed" title="Speed"></div>
 					<input type='range' min='0' max='4' class='popupInput' id='popupSpeedInput' />
+
+          <div class="popupRightItem" id="popupLabels" title="Labels"></div>
+          <!-- templates -->
+          <div id='popupLabelsInput' class='popupInput flex-col'>
+            <input type='text' id='new_annotation_label' placeholder='Add a new tag' class='editmode' />
+            <input class='annotation_labels_template' type='checkbox' id='' value='' style='display: none;' />
+            <label class='annotation_labels_template' for='' style='display: none;'></label>
+          </div>
 				</td>
 			</tr>
 		</table>
diff --git a/capsule-prototype/js/online-rekall/Project.js b/capsule-prototype/js/online-rekall/Project.js
index ebc832ca4e60938692fcc1c5943dff7cd465252a..6698c77fbccdc4cea39cda5b5c18a0085ad3607f 100644
--- a/capsule-prototype/js/online-rekall/Project.js
+++ b/capsule-prototype/js/online-rekall/Project.js
@@ -211,6 +211,8 @@ Project.prototype.timelineUpdate = function() {
 Project.prototype.analyse = function() {
 	$('#flattentimeline').html("<div id='flattentimeline_highlight'></div>");
 
+  var parsed_labels = $('input.annotation_labels').toArray().map(i => i.value);
+
 	//Analyse
 	Tags.flattenTimelineTags = [];
 	var filtredTags = new Array();
@@ -223,6 +225,34 @@ Project.prototype.analyse = function() {
 				rekall.sortings["horizontal"].analyseAdd(tag);
 				rekall.sortings["colors"]    .analyseAdd(tag);
 				Tags.flattenTimelineTags.push(tag);
+        var labels = tag.getMetadata('Rekall->Labels');
+        if (labels && labels != '') {
+          var input_template = $('input.annotation_labels_template').first();
+          var html_label_template = $('label.annotation_labels_template').first();
+          var _labels = labels.split(';');
+          for (var i in _labels) {
+            var label = _labels[i];
+            if (label == '') continue;
+            if (parsed_labels.indexOf(label) != -1)
+              continue;
+            parsed_labels.push(label);
+            var inp = input_template.clone();
+            var id = 'annotation_label_' + parsed_labels.indexOf(label);
+            inp.attr('id', id);
+            inp.attr('value', label);
+
+            var html_label = html_label_template.clone();
+            html_label.attr('for', id);
+            html_label.html(label);
+
+            html_label.show();
+            html_label.addClass('annotation_labels').removeClass('annotation_labels_template');
+            inp.addClass('annotation_labels').removeClass('annotation_labels_template');
+
+            $('#popupLabelsInput').append(inp);
+            $('#popupLabelsInput').append(html_label);
+          }
+        }
 			}
 		}
 	}
diff --git a/capsule-prototype/js/online-script.js b/capsule-prototype/js/online-script.js
index cf840c2f874b019e0445f1c964d5ae7481856245..afd9f67b8e4412ed7cd0213854288ff0472a7fc4 100644
--- a/capsule-prototype/js/online-script.js
+++ b/capsule-prototype/js/online-script.js
@@ -152,6 +152,34 @@ $(document).ready(function() {
 });
 
 function setEditionControls() {
+
+  $('#new_annotation_label').keypress(function(event) {
+    var keycode = (event.keyCode ? event.keyCode : event.which);
+    if (keycode != 13) {
+      return;
+    }
+    var label = $('#new_annotation_label').val();
+    var input = $('input.annotation_labels_template').first().clone();
+    var html_label = $('label.annotation_labels_template').first().clone();
+    var id = 'annotation_label_' + Math.floor((Math.random()*1000));
+
+    input.attr('name', 'annotation_labels');
+    input.attr('checked', 'true');
+    input.attr('id', id);
+    input.attr('value', label);
+
+    html_label.attr('for', id);
+    html_label.html(label);
+
+    html_label.show();
+    html_label.addClass('annotation_labels').removeClass('annotation_labels_template');
+    input.addClass('annotation_labels').removeClass('annotation_labels_template');
+
+    $('#popupLabelsInput').append(input);
+    $('#popupLabelsInput').append(html_label);
+    $('#new_annotation_label').val('');
+  })
+
 	//Drag&drop files
 	$(document).on({
 		dragenter: function(event) {
@@ -465,6 +493,13 @@ function setEditionControls() {
 		closeInputs();
 	});
 
+	$("#popupLabels").click(function(event){
+		event.stopPropagation();
+		closeInputs();
+		$(this).hide();
+		$("#popupLabelsInput").show().focus();
+	});
+
 	$("#popupSpeed").click(function(event){
 		event.stopPropagation();
 		closeInputs();
@@ -782,6 +817,21 @@ function closeInputs() {
 				if(newSpeed!="") $("#popupSpeed").html(get_str_for_speed(newSpeed)).removeClass("empty");
 				else $("#popupSpeed").html("+ Set video speed during this annotation ").addClass("empty");
 
+			} else if($(this).attr("id")=="popupLabelsInput") {
+
+				var keyDoc = $(this).parent().attr("keydoc");
+        var newLabels = '';
+        $('input.annotation_labels:checked')
+          .toArray().forEach(e => {
+            newLabels += e.value + ';';
+          })
+        setMetaFromDom(keyDoc, "Rekall->Labels", newLabels);
+
+        if (newLabels === '') {
+          $('#popupLabels').html('+ Set annotation labels ').addClass('empty');
+          $('#popupLabelsInput').hide();
+        }
+
 			} else if($(this).attr("id")=="popupAuthorInput") {
 
 				var keyDoc = $(this).parent().attr("keydoc");
@@ -803,7 +853,7 @@ function closeInputs() {
 				setMetaFromDom(keyDoc, "Rekall->Link", newLink);
 
 				if(newLink!="") {
-					if(rekall_common.owner.canEdit) $("#popupLink").html(newLink).removeClass("empty");
+          if(rekall_common.owner.canEdit) $("#popupLink").html(newLink).removeClass("empty");
 					else $("#popupLink").html("<a href='"+newLink+"' target='_blank'>"+newLink+"</a>").removeClass("empty");
 				}
 				else $("#popupLink").html("+ Add a link").addClass("empty");
@@ -873,6 +923,7 @@ function openMosaic() {
         let div=$('<div/>').addClass('mosaic_item').on('click', function() {tagOrDoc.openPopupEdit();});
         div.append($('<img/>').attr('src', url).attr('onerror', "this.src='../shared/css/images/img-document.png';"));
         div.append($('<span/>').addClass('caption').text(name));
+        div.attr('data-rekall-labels', tagOrDoc.getMetadata('Rekall->Labels'));
         return div;
     }
     function getFilterElement(text, color, callback, css_class) {
@@ -903,6 +954,7 @@ function openMosaic() {
         'mosaic_filter_item_all'
     ));
     container.append(filterdiv);
+    var labels = new Set();
     // TODO is there a better way to iterate over tags or documents ?
     for ( let [k, v] of  Object.entries(rekall.sortings.colors.categories)) {
         let categoryName = rekall.sortings.colors.getCategoryName(k)
@@ -924,9 +976,42 @@ function openMosaic() {
 
         for (let i in v.tags){
             grid.append(getMosaicItem(v.tags[i]));
+            var current_labels = v.tags[i].getMetadata('Rekall->Labels');
+            if (current_labels && current_labels != '') {
+              current_labels.split(';').forEach(l => {if (l != '') labels.add(l)});
+            }
         }
         container.append(category);
     }
+    labels.forEach(l => {
+      var button = $('<p/>').html(l);
+      button.my_state = undefined;
+      button.addClass('mosaic_label_filter');
+      button.click(ev => {
+        if (typeof(ev.target.my_state) === 'undefined') ev.target.my_state = true;
+        else ev.target.my_state = !ev.target.my_state;
+        if (ev.target.my_state) $(ev.target).addClass('mosaic_label_filter_enabled');
+        else $(ev.target).removeClass('mosaic_label_filter_enabled');
+        var labels = new Set();
+        $('.mosaic_label_filter').toArray().forEach(f => {
+          if (f.my_state == true)
+            labels.add(f.innerHTML);
+        });
+        if (!labels.size) {
+          $('.mosaic_label_filter').toArray().forEach(f => {
+            f.my_state = undefined;
+            $(f).removeClass('mosaic_label_filter_enabled');
+          });
+        }
+        $('.mosaic_item').toArray().forEach(t => {
+          if (!labels.size || Array.from(labels).map(l => t.dataset.rekallLabels.indexOf(l) != -1).includes(true))
+            $(t).show();
+          else
+            $(t).hide();
+        });
+      })
+      filterdiv.append(button);
+    });
 }
 
 function getTagGradientColor(tag) {
@@ -1014,6 +1099,19 @@ bgColorLeft = getTagGradientColor(tag);
 	if((speed)&&(speed!="")) $("#popupSpeed").html(get_str_for_speed(speed)).removeClass("empty");
 	else $("#popupSpeed").html("+ Set video speed during this annotation").addClass("empty");
 
+	var labels = tag.getMetadata("Rekall->Labels");
+  $('input.annotation_labels').attr('checked', false);
+  if (labels && labels != '') {
+    var _labels = labels.split(';');
+    $('input.annotation_labels').toArray().forEach(e => {
+      e.checked = (_labels.indexOf(e.value) != -1);
+    })
+    $('#popupLabelsInput').show();
+  } else {
+    $('#popupLabelsInput').hide();
+    $('#popupLabels').html('+ Add labels');
+  }
+
 	var comments = tag.getMetadata("Rekall->Comments");
 	if((comments)&&(comments!="")) $("#popupLegende").html(comments).removeClass("empty");
 	else $("#popupLegende").html("+ Add a comment").addClass("empty");