diff --git a/src/vte.cc b/src/vte.cc
index fbb831b1..53714cc4 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -6177,6 +6177,7 @@ vte_terminal_cellattr_equal(VteCellAttr const *attr1,
                 attr1->deco          == attr2->deco      &&
 	        attr1->underline     == attr2->underline &&
 	        attr1->strikethrough == attr2->strikethrough &&
+                attr1->overline      == attr2->overline  &&
 	        attr1->reverse       == attr2->reverse   &&
 	        attr1->blink         == attr2->blink     &&
                 attr1->invisible     == attr2->invisible &&
@@ -7603,6 +7604,8 @@ VteTerminalPrivate::apply_font_metrics(int cell_width,
         m_undercurl_thickness = m_line_thickness;
         m_strikethrough_position = char_spacing.top + char_ascent - char_height / 4;
         m_strikethrough_thickness = m_line_thickness;
+        m_overline_position = MAX (char_spacing.top + char_ascent / 8 - m_line_thickness, 0);
+        m_overline_thickness = m_line_thickness;
         m_regex_underline_position = char_spacing.top + char_height - 1;  /* FIXME */
         m_regex_underline_thickness = 1;  /* FIXME */
 
@@ -8125,6 +8128,8 @@ VteTerminalPrivate::VteTerminalPrivate(VteTerminal *t) :
         m_undercurl_thickness = 1;
 	m_strikethrough_position = 1;
         m_strikethrough_thickness = 1;
+        m_overline_position = 1;
+        m_overline_thickness = 1;
         m_regex_underline_position = 1;
         m_regex_underline_thickness = 1;
 
@@ -8931,6 +8936,7 @@ VteTerminalPrivate::draw_cells(struct _vte_draw_text_request *items,
                                bool italic,
                                guint underline,
                                bool strikethrough,
+                               bool overline,
                                bool hyperlink,
                                bool hilite,
                                bool boxed,
@@ -8950,10 +8956,10 @@ VteTerminalPrivate::draw_cells(struct _vte_draw_text_request *items,
 		}
 		tmp = g_string_free (str, FALSE);
                 g_printerr ("draw_cells('%s', fore=%d, back=%d, deco=%d, bold=%d,"
-                                " ul=%d, strike=%d,"
+                                " ul=%d, strike=%d, ol=%d"
                                 " hyperlink=%d, hilite=%d, boxed=%d)\n",
                                 tmp, fore, back, deco, bold,
-                                underline, strikethrough,
+                                underline, strikethrough, overline,
                                 hyperlink, hilite, boxed);
 		g_free (tmp);
 	}
@@ -8985,7 +8991,7 @@ VteTerminalPrivate::draw_cells(struct _vte_draw_text_request *items,
         /* Draw whatever SFX are required. Do this before drawing the letters,
          * so that if the descent of a letter crosses an underline of a different color,
          * it's the letter's color that wins. */
-        if (underline | strikethrough | hyperlink | hilite | boxed) {
+        if (underline | strikethrough | overline | hyperlink | hilite | boxed) {
 		i = 0;
 		do {
 			x = items[i].x;
@@ -9024,6 +9030,15 @@ VteTerminalPrivate::draw_cells(struct _vte_draw_text_request *items,
                                                     VTE_LINE_WIDTH,
                                                     &fg, VTE_DRAW_OPAQUE);
 			}
+                        if (overline) {
+                                _vte_draw_draw_line(m_draw,
+                                                    x,
+                                                    y + m_overline_position,
+                                                    x + (columns * column_width) - 1,
+                                                    y + m_overline_position + m_overline_thickness - 1,
+                                                    VTE_LINE_WIDTH,
+                                                    &fg, VTE_DRAW_OPAQUE);
+                        }
 			if (hilite) {
                                 _vte_draw_draw_line(m_draw,
                                                     x,
@@ -9278,6 +9293,7 @@ VteTerminalPrivate::draw_cells_with_attributes(struct _vte_draw_text_request *it
 					cells[j].attr.italic,
 					cells[j].attr.underline,
 					cells[j].attr.strikethrough,
+                                        cells[j].attr.overline,
                                         m_allow_hyperlink && cells[j].attr.hyperlink_idx != 0,
 					FALSE, FALSE, column_width, height);
 		j += g_unichar_to_utf8(items[i].c, scratch_buf);
@@ -9307,7 +9323,8 @@ VteTerminalPrivate::draw_rows(VteScreen *screen_,
         guint fore, nfore, back, nback, deco, ndeco, underline, nunderline;
         gboolean bold, nbold, italic, nitalic,
                  hyperlink, nhyperlink, hilite, nhilite,
-		 selected, nselected, strikethrough, nstrikethrough;
+		 selected, nselected, strikethrough, nstrikethrough,
+                 overline, noverline;
 	guint item_count;
 	const VteCell *cell;
 	VteRowData const* row_data;
@@ -9442,6 +9459,7 @@ VteTerminalPrivate::draw_rows(VteScreen *screen_,
 					(cell->c == ' ' &&
 					 !cell->attr.underline &&
                                          !cell->attr.strikethrough &&
+                                         !cell->attr.overline &&
                                          (!m_allow_hyperlink || cell->attr.hyperlink_idx == 0)) ||
 					cell->attr.fragment) {
 				if (++i >= end_column) {
@@ -9457,6 +9475,7 @@ VteTerminalPrivate::draw_rows(VteScreen *screen_,
                         determine_colors(cell, selected, &fore, &back, &deco);
 			underline = cell->attr.underline;
 			strikethrough = cell->attr.strikethrough;
+                        overline = cell->attr.overline;
                         hyperlink = (m_allow_hyperlink && cell->attr.hyperlink_idx != 0);
 			bold = cell->attr.bold;
 			italic = cell->attr.italic;
@@ -9494,7 +9513,7 @@ VteTerminalPrivate::draw_rows(VteScreen *screen_,
 						/* only break the run if we
 						 * are drawing attributes
 						 */
-                                                if (underline || strikethrough || hyperlink || hilite) {
+                                                if (underline || strikethrough || overline || hyperlink || hilite) {
 							break;
 						} else {
 							j++;
@@ -9529,6 +9548,10 @@ VteTerminalPrivate::draw_rows(VteScreen *screen_,
 					if (nstrikethrough != strikethrough) {
 						break;
 					}
+                                        noverline = cell->attr.overline;
+                                        if (noverline != overline) {
+                                                break;
+                                        }
                                         nhyperlink = (m_allow_hyperlink && cell->attr.hyperlink_idx != 0);
                                         if (nhyperlink != hyperlink) {
                                                 break;
@@ -9586,7 +9609,7 @@ fg_draw:
 					item_count,
                                         fore, back, deco, FALSE, FALSE,
 					bold, italic, underline,
-                                        strikethrough, hyperlink, hilite, FALSE,
+                                        strikethrough, overline, hyperlink, hilite, FALSE,
 					column_width, row_height);
 			item_count = 1;
 			/* We'll need to continue at the first cell which didn't
@@ -9818,6 +9841,7 @@ VteTerminalPrivate::paint_cursor()
                                                         cell->attr.italic,
                                                         cell->attr.underline,
                                                         cell->attr.strikethrough,
+                                                        cell->attr.overline,
                                                         m_allow_hyperlink && cell->attr.hyperlink_idx != 0,
                                                         FALSE,
                                                         FALSE,
@@ -9908,6 +9932,7 @@ VteTerminalPrivate::paint_im_preedit_string()
                                                 FALSE, /* italic */
                                                 0,     /* underline */
                                                 FALSE, /* strikethrough */
+                                                FALSE, /* overline */
                                                 FALSE, /* hyperlink */
                                                 FALSE, /* hilite */
                                                 TRUE,  /* boxed */
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index e284447e..5f83f033 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -659,6 +659,8 @@ public:
         long m_undercurl_thickness;
         long m_strikethrough_position;
         long m_strikethrough_thickness;
+        long m_overline_position;
+        long m_overline_thickness;
         long m_regex_underline_position;
         long m_regex_underline_thickness;
 
@@ -842,6 +844,7 @@ public:
                         bool italic,
                         guint underline,
                         bool strikethrough,
+                        bool overline,
                         bool hyperlink,
                         bool hilite,
                         bool boxed,
diff --git a/src/vterowdata.h b/src/vterowdata.h
index f441952a..da474fb0 100644
--- a/src/vterowdata.h
+++ b/src/vterowdata.h
@@ -64,7 +64,8 @@ typedef struct _VteCellAttr {
 	guint64 invisible: 1;
         /* 8-byte boundary */
         guint32 deco: 25;       /* decoration color (currently for underline) */
-        guint32 padding_unused: 7;
+        guint32 overline: 1;
+        guint32 padding_unused: 6;
         /* 12-byte boundary */
         guint32 hyperlink_idx;  /* a unique hyperlink index at a time for the ring's cells,
                                    0 means not a hyperlink, VTE_HYPERLINK_IDX_TARGET_IN_STREAM
@@ -127,6 +128,7 @@ static const VteCell basic_cell = {
 
                 0, /* invisible */
                 VTE_DEFAULT_FG, /* deco */
+                0, /* overline */
                 0, /* padding_unused */
                 0, /* hyperlink_idx */
 	}
diff --git a/src/vteseq.cc b/src/vteseq.cc
index a8a8ddc7..4944f88a 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -2027,6 +2027,12 @@ VteTerminalPrivate::seq_character_attributes(vte::parser::Params const& params)
 			/* default background */
                         m_defaults.attr.back = VTE_DEFAULT_BG;
 			break;
+                case 53:
+                        m_defaults.attr.overline = 1;
+                        break;
+                case 55:
+                        m_defaults.attr.overline = 0;
+                        break;
              /* case 58: was handled above at 38 to avoid code duplication */
                 case 59:
                         /* default decoration color, that is, same as the cell's foreground */
