diff --git a/dive.h b/dive.h
index 979f42916..ef5ff0f83 100644
--- a/dive.h
+++ b/dive.h
@@ -603,6 +603,7 @@ extern int parse_shearwater_buffer(sqlite3 *handle, const char *url, const char
 
 extern int parse_file(const char *filename);
 extern int parse_csv_file(const char *filename, int time, int depth, int temp, int po2f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int units);
+extern int parse_txt_file(const char *filename, const char *csv);
 extern int parse_manual_file(const char *filename, int separator_index, int units, int number, int date, int time, int duration, int location, int gps, int maxdepth, int meandepth, int buddy, int notes, int weight, int tags);
 
 extern int save_dives(const char *filename);
diff --git a/file.c b/file.c
index b1e258b75..175101575 100644
--- a/file.c
+++ b/file.c
@@ -226,7 +226,14 @@ timestamp_t parse_date(const char *date)
 enum csv_format {
 	CSV_DEPTH,
 	CSV_TEMP,
-	CSV_PRESSURE
+	CSV_PRESSURE,
+	POSEIDON_DEPTH,
+	POSEIDON_TEMP,
+	POSEIDON_SETPOINT,
+	POSEIDON_SENSOR1,
+	POSEIDON_SENSOR2,
+	POSEIDON_PRESSURE,
+	POSEIDON_DILUENT
 };
 
 static void add_sample_data(struct sample *sample, enum csv_format type, double val)
@@ -241,6 +248,27 @@ static void add_sample_data(struct sample *sample, enum csv_format type, double
 	case CSV_PRESSURE:
 		sample->cylinderpressure.mbar = psi_to_mbar(val * 4);
 		break;
+	case POSEIDON_DEPTH:
+		sample->depth.mm = val * 0.5 *1000;
+		break;
+	case POSEIDON_TEMP:
+		sample->temperature.mkelvin = C_to_mkelvin(val * 0.2);
+		break;
+	case POSEIDON_SETPOINT:
+		sample->setpoint.mbar = val * 10;
+		break;
+	case POSEIDON_SENSOR1:
+		sample->o2sensor[0].mbar = val * 10;
+		break;
+	case POSEIDON_SENSOR2:
+		sample->o2sensor[1].mbar = val * 10;
+		break;
+	case POSEIDON_PRESSURE:
+		sample->cylinderpressure.mbar = val * 1000;
+		break;
+	case POSEIDON_DILUENT:
+		sample->diluentpressure.mbar = val * 1000;
+		break;
 	}
 }
 
@@ -385,6 +413,182 @@ int parse_file(const char *filename)
 	return 0;
 }
 
+#define MATCH(buffer, pattern) \
+	memcmp(buffer, pattern, strlen(pattern))
+
+char *parse_mkvi_value(const char *haystack, const char *needle)
+{
+	char *lineptr, *valueptr, *endptr, *ret = NULL;
+
+	if ((lineptr = strstr(haystack, needle)) != NULL) {
+		if ((valueptr = strstr(lineptr, ": ")) != NULL) {
+			valueptr += 2;
+		}
+		if ((endptr = strstr(lineptr, "\n")) != NULL) {
+			*endptr = 0;
+			ret = strdup(valueptr);
+			*endptr = '\n';
+
+		}
+	}
+	return ret;
+}
+
+static int cur_cylinder_index;
+int parse_txt_file(const char *filename, const char *csv)
+{
+	struct memblock memtxt, memcsv;
+
+	if (readfile(filename, &memtxt) < 0) {
+		return report_error(translate("gettextFromC", "Failed to read '%s'"), filename);
+	}
+
+	/*
+	 * MkVI stores some information in .txt file but the whole profile and events are stored in .csv file. First
+	 * make sure the input .txt looks like proper MkVI file, then start parsing the .csv.
+	 */
+	if (MATCH(memtxt.buffer, "MkVI_Config") == 0) {
+		int d, m, y;
+		int hh = 0, mm = 0, ss = 0;
+		int prev_depth = 0, cur_sampletime = 0;
+		bool has_depth = false;
+		char *lineptr;
+
+		struct dive *dive;
+		struct divecomputer *dc;
+		struct tm cur_tm;
+		timestamp_t date;
+
+		if (sscanf(parse_mkvi_value(memtxt.buffer, "Dive started at"), "%d-%d-%d %d:%d:%d",
+					&y, &m, &d, &hh, &mm, &ss) != 6) {
+			return -1;
+		}
+
+		cur_tm.tm_year = y;
+		cur_tm.tm_mon = m - 1;
+		cur_tm.tm_mday = d;
+		cur_tm.tm_hour = hh;
+		cur_tm.tm_min = mm;
+		cur_tm.tm_sec = ss;
+
+		dive = alloc_dive();
+		dive->when = utc_mktime(&cur_tm);;
+		dive->dc.model = strdup("Poseidon MkVI Discovery");
+		dive->dc.deviceid = atoi(parse_mkvi_value(memtxt.buffer, "Rig Serial number"));
+		dive->dc.dctype = CCR;
+
+		dive->cylinder[cur_cylinder_index].type.size.mliter = 3000;
+		dive->cylinder[cur_cylinder_index].type.workingpressure.mbar = 200000;
+		dive->cylinder[cur_cylinder_index].type.description = strdup("3l Mk6");
+		cur_cylinder_index++;
+
+		dive->cylinder[cur_cylinder_index].type.size.mliter = 3000;
+		dive->cylinder[cur_cylinder_index].type.workingpressure.mbar = 200000;
+		dive->cylinder[cur_cylinder_index].type.description = strdup("3l Mk6");
+		cur_cylinder_index++;
+
+		dc = &dive->dc;
+
+		/*
+		 * Read samples from the CSV file. A sample contains all the lines with same timestamp. The CSV file has
+		 * the following format:
+		 *
+		 * timestamp, type, value
+		 *
+		 * And following fields are of interest to us:
+		 *
+		 * 	6	sensor1
+		 * 	7	sensor2
+		 * 	8	depth
+		 *	13	o2 tank pressure
+		 *	14	diluent tank pressure
+		 *	20	o2 setpoint
+		 *	39	water temp
+		 */
+
+		if (readfile(csv, &memcsv) < 0) {
+			return report_error(translate("gettextFromC", "Poseidon import failed: unable to read '%s'"), csv);
+		}
+		lineptr = memcsv.buffer;
+		for (;;) {
+			char *end;
+			double val;
+			struct sample *sample;
+			int type;
+			int value;
+			int sampletime;
+
+			/* Collect all the information for one sample */
+			sscanf(lineptr, "%d,%d,%d", &cur_sampletime, &type, &value);
+
+			has_depth = false;
+			sample = prepare_sample(dc);
+			sample->time.seconds = cur_sampletime;
+
+			do {
+				int i = sscanf(lineptr, "%d,%d,%d", &sampletime, &type, &value);
+				switch (i) {
+				case 3:
+					switch (type) {
+					case 6:
+						add_sample_data(sample, POSEIDON_SENSOR1, value);
+						break;
+					case 7:
+						add_sample_data(sample, POSEIDON_SENSOR2, value);
+						break;
+					case 8:
+						has_depth = true;
+						prev_depth = value;
+						add_sample_data(sample, POSEIDON_DEPTH, value);
+						break;
+					case 13:
+						add_sample_data(sample, POSEIDON_PRESSURE, value);
+						break;
+					case 14:
+						add_sample_data(sample, POSEIDON_DILUENT, value);
+						break;
+					case 20:
+						add_sample_data(sample, POSEIDON_SETPOINT, value);
+						break;
+					case 39:
+						add_sample_data(sample, POSEIDON_TEMP, value);
+						break;
+					default:
+						break;
+					} /* sample types */
+					break;
+				case EOF:
+					break;
+				default:
+					printf("Unable to parse input: %s\n", lineptr);
+					break;
+				}
+
+				lineptr = strchr(lineptr, '\n');
+				if (!lineptr || !*lineptr)
+					break;
+				lineptr++;
+
+				/* Grabbing next sample time */
+				sscanf(lineptr, "%d,%d,%d", &cur_sampletime, &type, &value);
+			} while (sampletime == cur_sampletime);
+
+			if (!has_depth)
+				add_sample_data(sample, POSEIDON_DEPTH, prev_depth);
+			finish_sample(dc);
+
+			if (!lineptr || !*lineptr)
+				break;
+		}
+		record_dive(dive);
+		return 1;
+	} else {
+		return report_error(translate("gettextFromC", "No matching DC found for file '%s'"), csv);
+	}
+
+	return 0;
+}
+
 #define MAXCOLDIGITS 3
 #define MAXCOLS 100
 int parse_csv_file(const char *filename, int timef, int depthf, int tempf, int po2f, int cnsf, int ndlf, int ttsf, int stopdepthf, int pressuref, int sepidx, const char *csvtemplate, int unitidx)
diff --git a/parse-xml.c b/parse-xml.c
index d54456e92..6da99b378 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -17,6 +17,7 @@
 
 #include "dive.h"
 #include "device.h"
+#include "membuffer.h"
 
 int verbose, quit;
 int metric = 1;
@@ -1738,6 +1739,13 @@ void parse_xml_buffer(const char *url, const char *buffer, int size,
 	xmlFreeDoc(doc);
 }
 
+void parse_mkvi_buffer(struct membuffer *txt, struct membuffer *csv, const char *starttime)
+{
+	dive_start();
+	divedate(starttime, &cur_dive->when);
+	dive_end();
+}
+
 extern int dm4_events(void *handle, int columns, char **data, char **column)
 {
 	event_start();
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index dfe8a2380..cb1ffea2d 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -1174,6 +1174,23 @@ void MainWindow::importFiles(const QStringList fileNames)
 	refreshDisplay();
 }
 
+void MainWindow::importTxtFiles(const QStringList fileNames)
+{
+	if (fileNames.isEmpty())
+		return;
+
+	QByteArray fileNamePtr, csv;
+
+	for (int i = 0; i < fileNames.size(); ++i) {
+		fileNamePtr = QFile::encodeName(fileNames.at(i));
+		csv = fileNamePtr.data();
+		csv.replace(strlen(csv.data()) - 3, 3, "csv");
+		parse_txt_file(fileNamePtr.data(), csv);
+	}
+	process_dives(true, false);
+	refreshDisplay();
+}
+
 void MainWindow::loadFiles(const QStringList fileNames)
 {
 	if (fileNames.isEmpty())
@@ -1208,14 +1225,15 @@ void MainWindow::on_actionImportDiveLog_triggered()
 	QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open dive log file"), lastUsedDir(),
 		tr("Dive log files (*.xml *.uddf *.udcf *.csv *.jlb *.dld *.sde *.db);;"
 			"XML files (*.xml);;UDDF/UDCF files(*.uddf *.udcf);;JDiveLog files(*.jlb);;"
-			"Suunto Files(*.sde *.db);;CSV Files(*.csv);;All Files(*)"));
+			"Suunto Files(*.sde *.db);;CSV Files(*.csv);;MkVI Files(*.txt);;All Files(*)"));
 
 	if (fileNames.isEmpty())
 		return;
 	updateLastUsedDir(QFileInfo(fileNames[0]).dir().path());
 
-	QStringList logFiles = fileNames.filter(QRegExp("^.*\\.(?!csv)", Qt::CaseInsensitive));
+	QStringList logFiles = fileNames.filter(QRegExp("^.*\\.(?!csv|?!txt)", Qt::CaseInsensitive));
 	QStringList csvFiles = fileNames.filter(".csv", Qt::CaseInsensitive);
+	QStringList txtFiles = fileNames.filter(".txt", Qt::CaseInsensitive);
 	if (logFiles.size()) {
 		importFiles(logFiles);
 	}
@@ -1226,6 +1244,10 @@ void MainWindow::on_actionImportDiveLog_triggered()
 		process_dives(true, false);
 		refreshDisplay();
 	}
+
+	if (txtFiles.size()) {
+		importTxtFiles(txtFiles);
+	}
 }
 
 void MainWindow::editCurrentDive()
diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h
index edf33a500..26f4176ac 100644
--- a/qt-ui/mainwindow.h
+++ b/qt-ui/mainwindow.h
@@ -73,6 +73,7 @@ public:
 	void enableDcShortcuts();
 	void loadFiles(const QStringList files);
 	void importFiles(const QStringList importFiles);
+	void importTxtFiles(const QStringList fileNames);
 	void cleanUpEmpty();
 	void setToolButtonsEnabled(bool enabled);
 	ProfileWidget2 *graphics() const;